mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
Some changes to migrate towards C++ and a multithreaded model
This commit is contained in:
parent
3f16ace678
commit
8d2f107d61
90 changed files with 7368 additions and 5981 deletions
348
FishsFish.xcodeproj/project.pbxproj
Normal file
348
FishsFish.xcodeproj/project.pbxproj
Normal file
|
@ -0,0 +1,348 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
D0A0850313B3ACEE0099B651 /* builtin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin.h; sourceTree = "<group>"; };
|
||||
D0A0850413B3ACEE0099B651 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
|
||||
D0A0850513B3ACEE0099B651 /* complete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = complete.h; sourceTree = "<group>"; };
|
||||
D0A0850613B3ACEE0099B651 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
D0A0850713B3ACEE0099B651 /* env_universal_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = env_universal_common.h; sourceTree = "<group>"; };
|
||||
D0A0850813B3ACEE0099B651 /* env_universal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = env_universal.h; sourceTree = "<group>"; };
|
||||
D0A0850913B3ACEE0099B651 /* env.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = env.h; sourceTree = "<group>"; };
|
||||
D0A0850A13B3ACEE0099B651 /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = "<group>"; };
|
||||
D0A0850B13B3ACEE0099B651 /* exec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exec.h; sourceTree = "<group>"; };
|
||||
D0A0850C13B3ACEE0099B651 /* expand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = expand.h; sourceTree = "<group>"; };
|
||||
D0A0850D13B3ACEE0099B651 /* fallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fallback.h; sourceTree = "<group>"; };
|
||||
D0A0850E13B3ACEE0099B651 /* function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = function.h; sourceTree = "<group>"; };
|
||||
D0A0850F13B3ACEE0099B651 /* halloc_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halloc_util.h; sourceTree = "<group>"; };
|
||||
D0A0851013B3ACEE0099B651 /* halloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halloc.h; sourceTree = "<group>"; };
|
||||
D0A0851113B3ACEE0099B651 /* highlight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = highlight.h; sourceTree = "<group>"; };
|
||||
D0A0851213B3ACEE0099B651 /* history.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = history.h; sourceTree = "<group>"; };
|
||||
D0A0851313B3ACEE0099B651 /* input_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input_common.h; sourceTree = "<group>"; };
|
||||
D0A0851413B3ACEE0099B651 /* input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input.h; sourceTree = "<group>"; };
|
||||
D0A0851513B3ACEE0099B651 /* intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intern.h; sourceTree = "<group>"; };
|
||||
D0A0851613B3ACEE0099B651 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = "<group>"; };
|
||||
D0A0851713B3ACEE0099B651 /* iothread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iothread.h; sourceTree = "<group>"; };
|
||||
D0A0851813B3ACEE0099B651 /* kill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kill.h; sourceTree = "<group>"; };
|
||||
D0A0851913B3ACEE0099B651 /* mimedb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mimedb.h; sourceTree = "<group>"; };
|
||||
D0A0851A13B3ACEE0099B651 /* output.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = output.h; sourceTree = "<group>"; };
|
||||
D0A0851B13B3ACEE0099B651 /* parse_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parse_util.h; sourceTree = "<group>"; };
|
||||
D0A0851C13B3ACEE0099B651 /* parser_keywords.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser_keywords.h; sourceTree = "<group>"; };
|
||||
D0A0851D13B3ACEE0099B651 /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
|
||||
D0A0851E13B3ACEE0099B651 /* path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = path.h; sourceTree = "<group>"; };
|
||||
D0A0851F13B3ACEE0099B651 /* print_help.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = print_help.h; sourceTree = "<group>"; };
|
||||
D0A0852013B3ACEE0099B651 /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = "<group>"; };
|
||||
D0A0852113B3ACEE0099B651 /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = "<group>"; };
|
||||
D0A0852213B3ACEE0099B651 /* sanity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sanity.h; sourceTree = "<group>"; };
|
||||
D0A0852313B3ACEE0099B651 /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
|
||||
D0A0852413B3ACEE0099B651 /* signal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = signal.h; sourceTree = "<group>"; };
|
||||
D0A0852513B3ACEE0099B651 /* tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tokenizer.h; sourceTree = "<group>"; };
|
||||
D0A0852613B3ACEE0099B651 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
|
||||
D0A0852713B3ACEE0099B651 /* wgetopt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wgetopt.h; sourceTree = "<group>"; };
|
||||
D0A0852813B3ACEE0099B651 /* wildcard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wildcard.h; sourceTree = "<group>"; };
|
||||
D0A0852913B3ACEE0099B651 /* wutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wutil.h; sourceTree = "<group>"; };
|
||||
D0A0852A13B3ACEE0099B651 /* xdgmime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmime.h; sourceTree = "<group>"; };
|
||||
D0A0852B13B3ACEE0099B651 /* xdgmimealias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimealias.h; sourceTree = "<group>"; };
|
||||
D0A0852C13B3ACEE0099B651 /* xdgmimeglob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeglob.h; sourceTree = "<group>"; };
|
||||
D0A0852D13B3ACEE0099B651 /* xdgmimeint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeint.h; sourceTree = "<group>"; };
|
||||
D0A0852E13B3ACEE0099B651 /* xdgmimemagic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimemagic.h; sourceTree = "<group>"; };
|
||||
D0A0852F13B3ACEE0099B651 /* xdgmimeparent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeparent.h; sourceTree = "<group>"; };
|
||||
D0A0853013B3ACEE0099B651 /* builtin_commandline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_commandline.cpp; sourceTree = "<group>"; };
|
||||
D0A0853113B3ACEE0099B651 /* builtin_complete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_complete.cpp; sourceTree = "<group>"; };
|
||||
D0A0853213B3ACEE0099B651 /* builtin_jobs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_jobs.cpp; sourceTree = "<group>"; };
|
||||
D0A0853313B3ACEE0099B651 /* builtin_set.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_set.cpp; sourceTree = "<group>"; };
|
||||
D0A0853413B3ACEE0099B651 /* builtin_ulimit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_ulimit.cpp; sourceTree = "<group>"; };
|
||||
D0A0853513B3ACEE0099B651 /* builtin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin.cpp; sourceTree = "<group>"; };
|
||||
D0A0853613B3ACEE0099B651 /* common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common.cpp; sourceTree = "<group>"; };
|
||||
D0A0853713B3ACEE0099B651 /* complete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = complete.cpp; sourceTree = "<group>"; };
|
||||
D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal_common.cpp; sourceTree = "<group>"; };
|
||||
D0A0853913B3ACEE0099B651 /* env_universal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal.cpp; sourceTree = "<group>"; };
|
||||
D0A0853A13B3ACEE0099B651 /* env.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env.cpp; sourceTree = "<group>"; };
|
||||
D0A0853B13B3ACEE0099B651 /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = "<group>"; };
|
||||
D0A0853C13B3ACEE0099B651 /* exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec.cpp; sourceTree = "<group>"; };
|
||||
D0A0853D13B3ACEE0099B651 /* expand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expand.cpp; sourceTree = "<group>"; };
|
||||
D0A0853E13B3ACEE0099B651 /* fallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fallback.cpp; sourceTree = "<group>"; };
|
||||
D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_indent.cpp; sourceTree = "<group>"; };
|
||||
D0A0854013B3ACEE0099B651 /* fish_pager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_pager.cpp; sourceTree = "<group>"; };
|
||||
D0A0854113B3ACEE0099B651 /* fish_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_tests.cpp; sourceTree = "<group>"; };
|
||||
D0A0854213B3ACEE0099B651 /* fish.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish.cpp; sourceTree = "<group>"; };
|
||||
D0A0854313B3ACEE0099B651 /* fishd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fishd.cpp; sourceTree = "<group>"; };
|
||||
D0A0854413B3ACEE0099B651 /* function.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = function.cpp; sourceTree = "<group>"; };
|
||||
D0A0854513B3ACEE0099B651 /* halloc_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halloc_util.cpp; sourceTree = "<group>"; };
|
||||
D0A0854613B3ACEE0099B651 /* halloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halloc.cpp; sourceTree = "<group>"; };
|
||||
D0A0854713B3ACEE0099B651 /* highlight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = highlight.cpp; sourceTree = "<group>"; };
|
||||
D0A0854813B3ACEE0099B651 /* history.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = history.cpp; sourceTree = "<group>"; };
|
||||
D0A0854913B3ACEE0099B651 /* input_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input_common.cpp; sourceTree = "<group>"; };
|
||||
D0A0854A13B3ACEE0099B651 /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
|
||||
D0A0854B13B3ACEE0099B651 /* intern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intern.cpp; sourceTree = "<group>"; };
|
||||
D0A0854C13B3ACEE0099B651 /* io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = io.cpp; sourceTree = "<group>"; };
|
||||
D0A0854D13B3ACEE0099B651 /* iothread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iothread.cpp; sourceTree = "<group>"; };
|
||||
D0A0854E13B3ACEE0099B651 /* key_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = key_reader.cpp; sourceTree = "<group>"; };
|
||||
D0A0854F13B3ACEE0099B651 /* kill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kill.cpp; sourceTree = "<group>"; };
|
||||
D0A0855013B3ACEE0099B651 /* mimedb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mimedb.cpp; sourceTree = "<group>"; };
|
||||
D0A0855113B3ACEE0099B651 /* output.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = output.cpp; sourceTree = "<group>"; };
|
||||
D0A0855213B3ACEE0099B651 /* parse_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_util.cpp; sourceTree = "<group>"; };
|
||||
D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_keywords.cpp; sourceTree = "<group>"; };
|
||||
D0A0855413B3ACEE0099B651 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; };
|
||||
D0A0855513B3ACEE0099B651 /* path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = path.cpp; sourceTree = "<group>"; };
|
||||
D0A0855613B3ACEE0099B651 /* print_help.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = print_help.cpp; sourceTree = "<group>"; };
|
||||
D0A0855713B3ACEE0099B651 /* proc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = proc.cpp; sourceTree = "<group>"; };
|
||||
D0A0855813B3ACEE0099B651 /* reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reader.cpp; sourceTree = "<group>"; };
|
||||
D0A0855913B3ACEE0099B651 /* sanity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sanity.cpp; sourceTree = "<group>"; };
|
||||
D0A0855A13B3ACEE0099B651 /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
|
||||
D0A0855B13B3ACEE0099B651 /* set_color.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = set_color.cpp; sourceTree = "<group>"; };
|
||||
D0A0855C13B3ACEE0099B651 /* signal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = signal.cpp; sourceTree = "<group>"; };
|
||||
D0A0855D13B3ACEE0099B651 /* tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tokenizer.cpp; sourceTree = "<group>"; };
|
||||
D0A0855E13B3ACEE0099B651 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
|
||||
D0A0855F13B3ACEE0099B651 /* wgetopt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wgetopt.cpp; sourceTree = "<group>"; };
|
||||
D0A0856013B3ACEE0099B651 /* wildcard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wildcard.cpp; sourceTree = "<group>"; };
|
||||
D0A0856113B3ACEE0099B651 /* wutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wutil.cpp; sourceTree = "<group>"; };
|
||||
D0A0856213B3ACEE0099B651 /* xdgmime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmime.cpp; sourceTree = "<group>"; };
|
||||
D0A0856313B3ACEE0099B651 /* xdgmimealias.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimealias.cpp; sourceTree = "<group>"; };
|
||||
D0A0856413B3ACEE0099B651 /* xdgmimeglob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeglob.cpp; sourceTree = "<group>"; };
|
||||
D0A0856513B3ACEE0099B651 /* xdgmimeint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeint.cpp; sourceTree = "<group>"; };
|
||||
D0A0856613B3ACEE0099B651 /* xdgmimemagic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimemagic.cpp; sourceTree = "<group>"; };
|
||||
D0A0856713B3ACEE0099B651 /* xdgmimeparent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeparent.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
D0A084F013B3AC130099B651 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0A0850313B3ACEE0099B651 /* builtin.h */,
|
||||
D0A0853013B3ACEE0099B651 /* builtin_commandline.cpp */,
|
||||
D0A0853113B3ACEE0099B651 /* builtin_complete.cpp */,
|
||||
D0A0853213B3ACEE0099B651 /* builtin_jobs.cpp */,
|
||||
D0A0853313B3ACEE0099B651 /* builtin_set.cpp */,
|
||||
D0A0853413B3ACEE0099B651 /* builtin_ulimit.cpp */,
|
||||
D0A0853513B3ACEE0099B651 /* builtin.cpp */,
|
||||
D0A0850413B3ACEE0099B651 /* common.h */,
|
||||
D0A0853613B3ACEE0099B651 /* common.cpp */,
|
||||
D0A0850513B3ACEE0099B651 /* complete.h */,
|
||||
D0A0853713B3ACEE0099B651 /* complete.cpp */,
|
||||
D0A0850613B3ACEE0099B651 /* config.h */,
|
||||
D0A0850713B3ACEE0099B651 /* env_universal_common.h */,
|
||||
D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */,
|
||||
D0A0850813B3ACEE0099B651 /* env_universal.h */,
|
||||
D0A0853913B3ACEE0099B651 /* env_universal.cpp */,
|
||||
D0A0850913B3ACEE0099B651 /* env.h */,
|
||||
D0A0853A13B3ACEE0099B651 /* env.cpp */,
|
||||
D0A0850A13B3ACEE0099B651 /* event.h */,
|
||||
D0A0853B13B3ACEE0099B651 /* event.cpp */,
|
||||
D0A0850B13B3ACEE0099B651 /* exec.h */,
|
||||
D0A0853C13B3ACEE0099B651 /* exec.cpp */,
|
||||
D0A0850C13B3ACEE0099B651 /* expand.h */,
|
||||
D0A0853D13B3ACEE0099B651 /* expand.cpp */,
|
||||
D0A0850D13B3ACEE0099B651 /* fallback.h */,
|
||||
D0A0853E13B3ACEE0099B651 /* fallback.cpp */,
|
||||
D0A0850E13B3ACEE0099B651 /* function.h */,
|
||||
D0A0854413B3ACEE0099B651 /* function.cpp */,
|
||||
D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */,
|
||||
D0A0854013B3ACEE0099B651 /* fish_pager.cpp */,
|
||||
D0A0854113B3ACEE0099B651 /* fish_tests.cpp */,
|
||||
D0A0854213B3ACEE0099B651 /* fish.cpp */,
|
||||
D0A0854313B3ACEE0099B651 /* fishd.cpp */,
|
||||
D0A0850F13B3ACEE0099B651 /* halloc_util.h */,
|
||||
D0A0851013B3ACEE0099B651 /* halloc.h */,
|
||||
D0A0854613B3ACEE0099B651 /* halloc.cpp */,
|
||||
D0A0854513B3ACEE0099B651 /* halloc_util.cpp */,
|
||||
D0A0851113B3ACEE0099B651 /* highlight.h */,
|
||||
D0A0854713B3ACEE0099B651 /* highlight.cpp */,
|
||||
D0A0851213B3ACEE0099B651 /* history.h */,
|
||||
D0A0854813B3ACEE0099B651 /* history.cpp */,
|
||||
D0A0851313B3ACEE0099B651 /* input_common.h */,
|
||||
D0A0854913B3ACEE0099B651 /* input_common.cpp */,
|
||||
D0A0851413B3ACEE0099B651 /* input.h */,
|
||||
D0A0854A13B3ACEE0099B651 /* input.cpp */,
|
||||
D0A0851513B3ACEE0099B651 /* intern.h */,
|
||||
D0A0854B13B3ACEE0099B651 /* intern.cpp */,
|
||||
D0A0851613B3ACEE0099B651 /* io.h */,
|
||||
D0A0854C13B3ACEE0099B651 /* io.cpp */,
|
||||
D0A0851713B3ACEE0099B651 /* iothread.h */,
|
||||
D0A0854D13B3ACEE0099B651 /* iothread.cpp */,
|
||||
D0A0851813B3ACEE0099B651 /* kill.h */,
|
||||
D0A0854F13B3ACEE0099B651 /* kill.cpp */,
|
||||
D0A0854E13B3ACEE0099B651 /* key_reader.cpp */,
|
||||
D0A0851913B3ACEE0099B651 /* mimedb.h */,
|
||||
D0A0855013B3ACEE0099B651 /* mimedb.cpp */,
|
||||
D0A0851A13B3ACEE0099B651 /* output.h */,
|
||||
D0A0855113B3ACEE0099B651 /* output.cpp */,
|
||||
D0A0851B13B3ACEE0099B651 /* parse_util.h */,
|
||||
D0A0855213B3ACEE0099B651 /* parse_util.cpp */,
|
||||
D0A0851C13B3ACEE0099B651 /* parser_keywords.h */,
|
||||
D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */,
|
||||
D0A0851D13B3ACEE0099B651 /* parser.h */,
|
||||
D0A0855413B3ACEE0099B651 /* parser.cpp */,
|
||||
D0A0851E13B3ACEE0099B651 /* path.h */,
|
||||
D0A0855513B3ACEE0099B651 /* path.cpp */,
|
||||
D0A0851F13B3ACEE0099B651 /* print_help.h */,
|
||||
D0A0855613B3ACEE0099B651 /* print_help.cpp */,
|
||||
D0A0852013B3ACEE0099B651 /* proc.h */,
|
||||
D0A0855713B3ACEE0099B651 /* proc.cpp */,
|
||||
D0A0852113B3ACEE0099B651 /* reader.h */,
|
||||
D0A0855813B3ACEE0099B651 /* reader.cpp */,
|
||||
D0A0852213B3ACEE0099B651 /* sanity.h */,
|
||||
D0A0855913B3ACEE0099B651 /* sanity.cpp */,
|
||||
D0A0852313B3ACEE0099B651 /* screen.h */,
|
||||
D0A0855A13B3ACEE0099B651 /* screen.cpp */,
|
||||
D0A0852413B3ACEE0099B651 /* signal.h */,
|
||||
D0A0855C13B3ACEE0099B651 /* signal.cpp */,
|
||||
D0A0855B13B3ACEE0099B651 /* set_color.cpp */,
|
||||
D0A0852513B3ACEE0099B651 /* tokenizer.h */,
|
||||
D0A0855D13B3ACEE0099B651 /* tokenizer.cpp */,
|
||||
D0A0852613B3ACEE0099B651 /* util.h */,
|
||||
D0A0855E13B3ACEE0099B651 /* util.cpp */,
|
||||
D0A0852713B3ACEE0099B651 /* wgetopt.h */,
|
||||
D0A0855F13B3ACEE0099B651 /* wgetopt.cpp */,
|
||||
D0A0852813B3ACEE0099B651 /* wildcard.h */,
|
||||
D0A0856013B3ACEE0099B651 /* wildcard.cpp */,
|
||||
D0A0852913B3ACEE0099B651 /* wutil.h */,
|
||||
D0A0856113B3ACEE0099B651 /* wutil.cpp */,
|
||||
D0A0852A13B3ACEE0099B651 /* xdgmime.h */,
|
||||
D0A0856213B3ACEE0099B651 /* xdgmime.cpp */,
|
||||
D0A0852B13B3ACEE0099B651 /* xdgmimealias.h */,
|
||||
D0A0856313B3ACEE0099B651 /* xdgmimealias.cpp */,
|
||||
D0A0852C13B3ACEE0099B651 /* xdgmimeglob.h */,
|
||||
D0A0856413B3ACEE0099B651 /* xdgmimeglob.cpp */,
|
||||
D0A0852D13B3ACEE0099B651 /* xdgmimeint.h */,
|
||||
D0A0856513B3ACEE0099B651 /* xdgmimeint.cpp */,
|
||||
D0A0852E13B3ACEE0099B651 /* xdgmimemagic.h */,
|
||||
D0A0856613B3ACEE0099B651 /* xdgmimemagic.cpp */,
|
||||
D0A0852F13B3ACEE0099B651 /* xdgmimeparent.h */,
|
||||
D0A0856713B3ACEE0099B651 /* xdgmimeparent.cpp */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXLegacyTarget section */
|
||||
D0A084F713B3AC130099B651 /* FishsFish */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "-f Makefile.cpp -k ${ACTION}";
|
||||
buildConfigurationList = D0A084FA13B3AC130099B651 /* Build configuration list for PBXLegacyTarget "FishsFish" */;
|
||||
buildPhases = (
|
||||
);
|
||||
buildToolPath = /usr/bin/make;
|
||||
buildWorkingDirectory = "";
|
||||
dependencies = (
|
||||
);
|
||||
name = FishsFish;
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = FishsFish;
|
||||
};
|
||||
/* End PBXLegacyTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
D0A084F213B3AC130099B651 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0420;
|
||||
};
|
||||
buildConfigurationList = D0A084F513B3AC130099B651 /* Build configuration list for PBXProject "FishsFish" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = D0A084F013B3AC130099B651;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
D0A084F713B3AC130099B651 /* FishsFish */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
D0A084F813B3AC130099B651 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
D0A084F913B3AC130099B651 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
D0A084FB13B3AC130099B651 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUGGING_SYMBOLS = YES;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
D0A084FC13B3AC130099B651 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
D0A084F513B3AC130099B651 /* Build configuration list for PBXProject "FishsFish" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
D0A084F813B3AC130099B651 /* Debug */,
|
||||
D0A084F913B3AC130099B651 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D0A084FA13B3AC130099B651 /* Build configuration list for PBXLegacyTarget "FishsFish" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
D0A084FB13B3AC130099B651 /* Debug */,
|
||||
D0A084FC13B3AC130099B651 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = D0A084F213B3AC130099B651 /* Project object */;
|
||||
}
|
538
builtin.cpp
538
builtin.cpp
File diff suppressed because it is too large
Load diff
10
builtin.h
10
builtin.h
|
@ -64,7 +64,7 @@ enum
|
|||
#define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" )
|
||||
|
||||
/**
|
||||
Error message for insufficient number of arguments
|
||||
Error message for insufficient number of arguments
|
||||
*/
|
||||
#define BUILTIN_FOR_ERR_COUNT _( L"%ls: Expected at least two arguments, got %d\n")
|
||||
|
||||
|
@ -108,7 +108,7 @@ extern int builtin_err_redirect;
|
|||
|
||||
|
||||
/**
|
||||
Initialize builtin data.
|
||||
Initialize builtin data.
|
||||
*/
|
||||
void builtin_init();
|
||||
|
||||
|
@ -123,11 +123,11 @@ void builtin_destroy();
|
|||
int builtin_exists( wchar_t *cmd );
|
||||
|
||||
/**
|
||||
Execute a builtin command
|
||||
Execute a builtin command
|
||||
|
||||
\param argv Array containing the command and parameters
|
||||
\param argv Array containing the command and parameters
|
||||
of the builtin. The list is terminated by a
|
||||
null pointer. This syntax resembles the syntax
|
||||
null pointer. This syntax resembles the syntax
|
||||
for exec.
|
||||
\param io the io redirections to perform on this builtin.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/** \file builtin_commandline.c Functions defining the commandline builtin
|
||||
|
||||
Functions used for implementing the commandline builtin.
|
||||
Functions used for implementing the commandline builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
@ -96,20 +96,20 @@ static void replace_part( const wchar_t *begin,
|
|||
const wchar_t *buff = get_buffer();
|
||||
string_buffer_t out;
|
||||
int out_pos=get_cursor_pos();
|
||||
|
||||
|
||||
sb_init( &out );
|
||||
|
||||
sb_append_substring( &out, buff, begin-buff );
|
||||
|
||||
|
||||
switch( append_mode)
|
||||
{
|
||||
case REPLACE_MODE:
|
||||
{
|
||||
|
||||
|
||||
sb_append( &out, insert );
|
||||
out_pos = wcslen( insert ) + (begin-buff);
|
||||
out_pos = wcslen( insert ) + (begin-buff);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
case APPEND_MODE:
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ static void replace_part( const wchar_t *begin,
|
|||
sb_append_substring( &out, begin, cursor );
|
||||
sb_append( &out, insert );
|
||||
sb_append_substring( &out, begin+cursor, end-begin-cursor );
|
||||
out_pos += wcslen( insert );
|
||||
out_pos += wcslen( insert );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ static void replace_part( const wchar_t *begin,
|
|||
reader_set_buffer( (wchar_t *)out.buff, out_pos );
|
||||
sb_destroy( &out );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Output the specified selection.
|
||||
|
||||
|
@ -140,15 +140,15 @@ static void replace_part( const wchar_t *begin,
|
|||
\param cut_at_cursor whether printing should stop at the surrent cursor position
|
||||
\param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens
|
||||
*/
|
||||
static void write_part( const wchar_t *begin,
|
||||
const wchar_t *end,
|
||||
int cut_at_cursor,
|
||||
static void write_part( const wchar_t *begin,
|
||||
const wchar_t *end,
|
||||
int cut_at_cursor,
|
||||
int tokenize )
|
||||
{
|
||||
{
|
||||
tokenizer tok;
|
||||
string_buffer_t out;
|
||||
wchar_t *buff;
|
||||
int pos;
|
||||
size_t pos;
|
||||
|
||||
pos = get_cursor_pos()-(begin-get_buffer());
|
||||
|
||||
|
@ -157,7 +157,7 @@ static void write_part( const wchar_t *begin,
|
|||
buff = wcsndup( begin, end-begin );
|
||||
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
|
||||
sb_init( &out );
|
||||
|
||||
|
||||
for( tok_init( &tok, buff, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok );
|
||||
tok_next( &tok ) )
|
||||
|
@ -165,23 +165,23 @@ static void write_part( const wchar_t *begin,
|
|||
if( (cut_at_cursor) &&
|
||||
(tok_get_pos( &tok)+wcslen(tok_last( &tok)) >= pos) )
|
||||
break;
|
||||
|
||||
|
||||
switch( tok_last_type( &tok ) )
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
wchar_t *tmp = unescape( tok_last( &tok ), UNESCAPE_INCOMPLETE );
|
||||
sb_append( &out, tmp, L"\n", (void *)0 );
|
||||
sb_append( &out, tmp, L"\n", NULL );
|
||||
free( tmp );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sb_append( sb_out,
|
||||
(wchar_t *)out.buff );
|
||||
|
||||
|
||||
free( buff );
|
||||
tok_destroy( &tok );
|
||||
sb_destroy( &out );
|
||||
|
@ -189,10 +189,10 @@ static void write_part( const wchar_t *begin,
|
|||
else
|
||||
{
|
||||
wchar_t *buff, *esc;
|
||||
|
||||
|
||||
if( cut_at_cursor )
|
||||
{
|
||||
end = begin+pos;
|
||||
end = begin+pos;
|
||||
}
|
||||
|
||||
buff = wcsndup( begin, end-begin );
|
||||
|
@ -202,10 +202,10 @@ static void write_part( const wchar_t *begin,
|
|||
|
||||
sb_append( sb_out, esc );
|
||||
sb_append( sb_out, L"\n" );
|
||||
|
||||
|
||||
free( esc );
|
||||
free( buff );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,14 @@ static int builtin_commandline( wchar_t **argv )
|
|||
|
||||
int buffer_part=0;
|
||||
int cut_at_cursor=0;
|
||||
|
||||
|
||||
int argc = builtin_count_args( argv );
|
||||
int append_mode=0;
|
||||
|
||||
int function_mode = 0;
|
||||
|
||||
int tokenize = 0;
|
||||
|
||||
|
||||
int tokenize = 0;
|
||||
|
||||
int cursor_mode = 0;
|
||||
int line_mode = 0;
|
||||
int search_mode = 0;
|
||||
|
@ -254,11 +254,11 @@ static int builtin_commandline( wchar_t **argv )
|
|||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sb_append( sb_err,
|
||||
argv[0],
|
||||
L": Can not set commandline in non-interactive mode\n",
|
||||
(void *)0 );
|
||||
NULL );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
@ -293,11 +293,11 @@ static int builtin_commandline( wchar_t **argv )
|
|||
{
|
||||
L"current-token", no_argument, 0, 't'
|
||||
}
|
||||
,
|
||||
,
|
||||
{
|
||||
L"current-buffer", no_argument, 0, 'b'
|
||||
}
|
||||
,
|
||||
,
|
||||
{
|
||||
L"cut-at-cursor", no_argument, 0, 'c'
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
{
|
||||
L"input", required_argument, 0, 'I'
|
||||
}
|
||||
,
|
||||
|
@ -331,21 +331,21 @@ static int builtin_commandline( wchar_t **argv )
|
|||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"abijpctwforhI:CLS",
|
||||
long_options,
|
||||
argv,
|
||||
L"abijpctwforhI:CLS",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
|
@ -358,7 +358,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
case L'a':
|
||||
append_mode = APPEND_MODE;
|
||||
break;
|
||||
|
@ -366,8 +366,8 @@ static int builtin_commandline( wchar_t **argv )
|
|||
case L'b':
|
||||
buffer_part = STRING_MODE;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
case L'i':
|
||||
append_mode = INSERT_MODE;
|
||||
break;
|
||||
|
@ -375,11 +375,11 @@ static int builtin_commandline( wchar_t **argv )
|
|||
case L'r':
|
||||
append_mode = REPLACE_MODE;
|
||||
break;
|
||||
|
||||
|
||||
case 'c':
|
||||
cut_at_cursor=1;
|
||||
break;
|
||||
|
||||
|
||||
case 't':
|
||||
buffer_part = TOKEN_MODE;
|
||||
break;
|
||||
|
@ -404,33 +404,33 @@ static int builtin_commandline( wchar_t **argv )
|
|||
current_buffer = woptarg;
|
||||
current_cursor_pos = wcslen( woptarg );
|
||||
break;
|
||||
|
||||
|
||||
case 'C':
|
||||
cursor_mode = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'L':
|
||||
line_mode = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'S':
|
||||
search_mode = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( function_mode )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
/*
|
||||
Check for invalid switch combinations
|
||||
*/
|
||||
|
@ -439,18 +439,18 @@ static int builtin_commandline( wchar_t **argv )
|
|||
sb_printf(sb_err,
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( argc == woptind )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_MISSING,
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
@ -476,34 +476,34 @@ static int builtin_commandline( wchar_t **argv )
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check for invalid switch combinations
|
||||
*/
|
||||
if( (search_mode || line_mode || cursor_mode) && (argc-woptind > 1) )
|
||||
{
|
||||
|
||||
|
||||
sb_append( sb_err,
|
||||
argv[0],
|
||||
L": Too many arguments\n",
|
||||
(void *)0 );
|
||||
NULL );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode) )
|
||||
{
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( (tokenize || cut_at_cursor) && (argc-woptind) )
|
||||
{
|
||||
|
@ -511,7 +511,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
BUILTIN_ERR_COMBO2,
|
||||
argv[0],
|
||||
L"--cut-at-cursor and --tokenize can not be used when setting the commandline" );
|
||||
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
@ -524,7 +524,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
argv[0],
|
||||
L"insertion mode switches can not be used when not in insertion mode" );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -535,7 +535,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
{
|
||||
append_mode = REPLACE_MODE;
|
||||
}
|
||||
|
||||
|
||||
if( !buffer_part )
|
||||
{
|
||||
buffer_part = STRING_MODE;
|
||||
|
@ -548,7 +548,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
wchar_t *endptr;
|
||||
int new_pos;
|
||||
errno = 0;
|
||||
|
||||
|
||||
new_pos = wcstol( argv[woptind], &endptr, 10 );
|
||||
if( *endptr || errno )
|
||||
{
|
||||
|
@ -558,7 +558,7 @@ static int builtin_commandline( wchar_t **argv )
|
|||
argv[woptind] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
|
||||
|
||||
current_buffer = reader_get_buffer();
|
||||
new_pos = maxi( 0, mini( new_pos, wcslen( current_buffer ) ) );
|
||||
reader_set_buffer( current_buffer, new_pos );
|
||||
|
@ -569,98 +569,98 @@ static int builtin_commandline( wchar_t **argv )
|
|||
sb_printf( sb_out, L"%d\n", reader_get_cursor_pos() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( line_mode )
|
||||
{
|
||||
int pos = reader_get_cursor_pos();
|
||||
wchar_t *buff = reader_get_buffer();
|
||||
sb_printf( sb_out, L"%d\n", parse_util_lineno( buff, pos ) );
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( search_mode )
|
||||
{
|
||||
return !reader_search_mode();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch( buffer_part )
|
||||
{
|
||||
case STRING_MODE:
|
||||
{
|
||||
{
|
||||
begin = get_buffer();
|
||||
end = begin+wcslen(begin);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case PROCESS_MODE:
|
||||
{
|
||||
parse_util_process_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&begin,
|
||||
&end );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case JOB_MODE:
|
||||
{
|
||||
parse_util_job_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&end );
|
||||
break;
|
||||
&end );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOKEN_MODE:
|
||||
{
|
||||
parse_util_token_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&end,
|
||||
&begin,
|
||||
&end,
|
||||
0, 0 );
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
switch(argc-woptind)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
{
|
||||
write_part( begin, end, cut_at_cursor, tokenize );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
replace_part( begin, end, argv[woptind], append_mode );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
string_buffer_t sb;
|
||||
int i;
|
||||
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
|
||||
sb_append( &sb, argv[woptind] );
|
||||
|
||||
|
||||
for( i=woptind+1; i<argc; i++ )
|
||||
{
|
||||
sb_append( &sb, L"\n" );
|
||||
sb_append( &sb, argv[i] );
|
||||
}
|
||||
|
||||
|
||||
replace_part( begin, end, (wchar_t *)sb.buff, append_mode );
|
||||
sb_destroy( &sb );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/** \file builtin_complete.c Functions defining the complete builtin
|
||||
|
||||
Functions used for implementing the complete builtin.
|
||||
Functions used for implementing the complete builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
@ -26,7 +26,7 @@ Functions used for implementing the complete builtin.
|
|||
|
||||
|
||||
/**
|
||||
Internal storage for the builtin_get_temporary_buffer() function.
|
||||
Internal storage for the builtin_complete_get_temporary_buffer() function.
|
||||
*/
|
||||
static const wchar_t *temporary_buffer;
|
||||
|
||||
|
@ -46,8 +46,8 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
int cmd_type,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc,
|
||||
|
@ -55,10 +55,10 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
{
|
||||
int i;
|
||||
const wchar_t *s;
|
||||
|
||||
|
||||
for( s=short_opt; *s; s++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
*s,
|
||||
0,
|
||||
|
@ -69,10 +69,10 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( gnu_opt ); i++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
(wchar_t *)al_get(gnu_opt, i ),
|
||||
|
@ -83,10 +83,10 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( old_opt ); i++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
(wchar_t *)al_get(old_opt, i ),
|
||||
|
@ -96,11 +96,11 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
comp,
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
}
|
||||
|
||||
if( al_get_count( old_opt )+al_get_count( gnu_opt )+wcslen(short_opt) == 0 )
|
||||
{
|
||||
complete_add( cmd,
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
0,
|
||||
|
@ -110,18 +110,18 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
|||
comp,
|
||||
desc,
|
||||
flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_add( array_list_t *cmd,
|
||||
static void builtin_complete_add( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
int authoritative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
|
@ -129,50 +129,50 @@ static void builtin_complete_add( array_list_t *cmd,
|
|||
int flags )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( cmd ); i++ )
|
||||
{
|
||||
builtin_complete_add2( al_get( cmd, i ),
|
||||
builtin_complete_add2( (const wchar_t *)al_get( cmd, i ),
|
||||
COMMAND,
|
||||
short_opt,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
old_opt,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc,
|
||||
flags );
|
||||
|
||||
if( authoritative != -1 )
|
||||
{
|
||||
complete_set_authoritative( al_get( cmd, i ),
|
||||
complete_set_authoritative( (const wchar_t *)al_get( cmd, i ),
|
||||
COMMAND,
|
||||
authoritative );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( path ); i++ )
|
||||
{
|
||||
builtin_complete_add2( al_get( path, i ),
|
||||
builtin_complete_add2( (const wchar_t *)al_get( path, i ),
|
||||
PATH,
|
||||
short_opt,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
old_opt,
|
||||
result_mode,
|
||||
condition,
|
||||
comp,
|
||||
desc,
|
||||
flags );
|
||||
|
||||
if( authoritative != -1 )
|
||||
{
|
||||
complete_set_authoritative( al_get( path, i ),
|
||||
complete_set_authoritative( (const wchar_t *)al_get( path, i ),
|
||||
PATH,
|
||||
authoritative );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,17 +181,17 @@ static void builtin_complete_add( array_list_t *cmd,
|
|||
static void builtin_complete_remove3( wchar_t *cmd,
|
||||
int cmd_type,
|
||||
wchar_t short_opt,
|
||||
array_list_t *long_opt )
|
||||
array_list_t *long_opt )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( long_opt ); i++ )
|
||||
{
|
||||
complete_remove( cmd,
|
||||
cmd_type,
|
||||
short_opt,
|
||||
(wchar_t *)al_get( long_opt, i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,7 +214,7 @@ static void builtin_complete_remove2( wchar_t *cmd,
|
|||
cmd_type,
|
||||
*s,
|
||||
0 );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -239,47 +239,48 @@ static void builtin_complete_remove2( wchar_t *cmd,
|
|||
cmd_type,
|
||||
0,
|
||||
old_opt );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Silly function
|
||||
*/
|
||||
static void builtin_complete_remove( array_list_t *cmd,
|
||||
static void builtin_complete_remove( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt )
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( cmd ); i++ )
|
||||
{
|
||||
builtin_complete_remove2( (wchar_t *)al_get( cmd, i ),
|
||||
COMMAND,
|
||||
short_opt,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt );
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( path ); i++ )
|
||||
{
|
||||
builtin_complete_remove2( (wchar_t *)al_get( path, i ),
|
||||
PATH,
|
||||
short_opt,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
const wchar_t *builtin_complete_get_temporary_buffer()
|
||||
{
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
return temporary_buffer;
|
||||
}
|
||||
|
||||
|
@ -290,61 +291,62 @@ const wchar_t *builtin_complete_get_temporary_buffer()
|
|||
*/
|
||||
static int builtin_complete( wchar_t **argv )
|
||||
{
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
int res=0;
|
||||
int argc=0;
|
||||
int result_mode=SHARED;
|
||||
int remove = 0;
|
||||
int authoritative = -1;
|
||||
int flags = COMPLETE_AUTO_SPACE;
|
||||
|
||||
|
||||
string_buffer_t short_opt;
|
||||
array_list_t gnu_opt, old_opt;
|
||||
wchar_t *comp=L"", *desc=L"", *condition=L"";
|
||||
const wchar_t *comp=L"", *desc=L"", *condition=L"";
|
||||
|
||||
wchar_t *do_complete = 0;
|
||||
|
||||
|
||||
array_list_t cmd;
|
||||
array_list_t path;
|
||||
|
||||
static int recursion_level=0;
|
||||
|
||||
|
||||
al_init( &cmd );
|
||||
al_init( &path );
|
||||
sb_init( &short_opt );
|
||||
al_init( &gnu_opt );
|
||||
al_init( &old_opt );
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
|
||||
woptind=0;
|
||||
|
||||
|
||||
while( res == 0 )
|
||||
{
|
||||
static const struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"exclusive", no_argument, 0, 'x'
|
||||
L"exclusive", no_argument, 0, 'x'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"no-files", no_argument, 0, 'f'
|
||||
L"no-files", no_argument, 0, 'f'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"require-parameter", no_argument, 0, 'r'
|
||||
L"require-parameter", no_argument, 0, 'r'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"path", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
,
|
||||
{
|
||||
L"command", required_argument, 0, 'c'
|
||||
L"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
,
|
||||
{
|
||||
L"short-option", required_argument, 0, 's'
|
||||
L"short-option", required_argument, 0, 's'
|
||||
}
|
||||
,
|
||||
{
|
||||
|
@ -352,7 +354,7 @@ static int builtin_complete( wchar_t **argv )
|
|||
}
|
||||
,
|
||||
{
|
||||
L"old-option", required_argument, 0, 'o'
|
||||
L"old-option", required_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
|
@ -387,22 +389,22 @@ static int builtin_complete( wchar_t **argv )
|
|||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeuAn:C::h",
|
||||
long_options,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeuAn:C::h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
|
@ -414,23 +416,23 @@ static int builtin_complete( wchar_t **argv )
|
|||
long_options[opt_index].name );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
|
||||
case 'x':
|
||||
result_mode |= EXCLUSIVE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
||||
case 'f':
|
||||
result_mode |= NO_FILES;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
|
||||
case 'r':
|
||||
result_mode |= NO_COMMON;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
|
||||
case 'p':
|
||||
case 'c':
|
||||
{
|
||||
wchar_t *a = unescape( woptarg, 1);
|
||||
|
@ -441,31 +443,31 @@ static int builtin_complete( wchar_t **argv )
|
|||
else
|
||||
{
|
||||
sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg );
|
||||
res = 1;
|
||||
}
|
||||
res = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'd':
|
||||
desc = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'u':
|
||||
authoritative=0;
|
||||
break;
|
||||
|
||||
|
||||
case 'A':
|
||||
authoritative=1;
|
||||
break;
|
||||
|
||||
|
||||
case 's':
|
||||
sb_append( &short_opt, woptarg );
|
||||
break;
|
||||
|
||||
|
||||
case 'l':
|
||||
al_push( &gnu_opt, woptarg );
|
||||
break;
|
||||
|
||||
|
||||
case 'o':
|
||||
al_push( &old_opt, woptarg );
|
||||
break;
|
||||
|
@ -473,7 +475,7 @@ static int builtin_complete( wchar_t **argv )
|
|||
case 'a':
|
||||
comp = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'e':
|
||||
remove = 1;
|
||||
break;
|
||||
|
@ -481,22 +483,22 @@ static int builtin_complete( wchar_t **argv )
|
|||
case 'n':
|
||||
condition = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'C':
|
||||
do_complete = woptarg?woptarg:reader_get_buffer();
|
||||
break;
|
||||
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
|
||||
case '?':
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( !res )
|
||||
|
@ -506,17 +508,17 @@ static int builtin_complete( wchar_t **argv )
|
|||
if( parser_test( condition, 0, 0, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Condition '%ls' contained a syntax error\n",
|
||||
L"%ls: Condition '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
condition );
|
||||
|
||||
|
||||
parser_test( condition, 0, sb_err, argv[0] );
|
||||
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( comp && wcslen( comp ) )
|
||||
|
@ -524,12 +526,12 @@ static int builtin_complete( wchar_t **argv )
|
|||
if( parser_test_args( comp, 0, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Completion '%ls' contained a syntax error\n",
|
||||
L"%ls: Completion '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
comp );
|
||||
|
||||
|
||||
parser_test_args( comp, sb_err, argv[0] );
|
||||
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
@ -547,22 +549,22 @@ static int builtin_complete( wchar_t **argv )
|
|||
wchar_t *token;
|
||||
|
||||
parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 );
|
||||
|
||||
temporary_buffer = do_complete;
|
||||
|
||||
temporary_buffer = do_complete;
|
||||
|
||||
if( recursion_level < 1 )
|
||||
{
|
||||
recursion_level++;
|
||||
|
||||
|
||||
comp = al_halloc( 0 );
|
||||
|
||||
|
||||
complete( do_complete, comp );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
completion_t *next = (completion_t *)al_get( comp, i );
|
||||
wchar_t *prepend;
|
||||
|
||||
const wchar_t *prepend;
|
||||
|
||||
if( next->flags & COMPLETE_NO_CASE )
|
||||
{
|
||||
prepend = L"";
|
||||
|
@ -571,7 +573,7 @@ static int builtin_complete( wchar_t **argv )
|
|||
{
|
||||
prepend = token;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( next->description )
|
||||
{
|
||||
|
@ -582,17 +584,17 @@ static int builtin_complete( wchar_t **argv )
|
|||
sb_printf( sb_out, L"%ls%ls\n", prepend, next->completion );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
halloc_free( comp );
|
||||
recursion_level--;
|
||||
}
|
||||
|
||||
temporary_buffer = prev_temporary_buffer;
|
||||
|
||||
|
||||
temporary_buffer = prev_temporary_buffer;
|
||||
|
||||
}
|
||||
else if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
@ -603,7 +605,7 @@ static int builtin_complete( wchar_t **argv )
|
|||
{
|
||||
/* No arguments specified, meaning we print the definitions of
|
||||
* all specified completions to stdout.*/
|
||||
complete_print( sb_out );
|
||||
complete_print( sb_out );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -613,26 +615,26 @@ static int builtin_complete( wchar_t **argv )
|
|||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt );
|
||||
&old_opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_add( &cmd,
|
||||
builtin_complete_add( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt,
|
||||
result_mode,
|
||||
&old_opt,
|
||||
result_mode,
|
||||
authoritative,
|
||||
condition,
|
||||
comp,
|
||||
desc,
|
||||
flags );
|
||||
flags );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_foreach( &cmd, &free );
|
||||
al_foreach( &path, &free );
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ static void builtin_jobs_print( job_t *j, int mode, int header )
|
|||
L"\t",
|
||||
j->command,
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ static int builtin_jobs( wchar_t **argv )
|
|||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
|
|
326
builtin_set.cpp
326
builtin_set.cpp
|
@ -1,6 +1,6 @@
|
|||
/** \file builtin_set.c Functions defining the set builtin
|
||||
|
||||
Functions used for implementing the set builtin.
|
||||
Functions used for implementing the set builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
@ -61,19 +61,19 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
|||
int i;
|
||||
int retcode = 0;
|
||||
wchar_t *val_str=0;
|
||||
|
||||
|
||||
if( is_path_variable( key ) )
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
int show_perror = 0;
|
||||
int show_hint = 0;
|
||||
|
||||
|
||||
struct stat buff;
|
||||
wchar_t *dir = (wchar_t *)al_get( val, i );
|
||||
|
||||
|
||||
if( wstat( dir, &buff ) )
|
||||
{
|
||||
error = 1;
|
||||
|
@ -83,55 +83,55 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
|||
if( !( S_ISDIR(buff.st_mode) ) )
|
||||
{
|
||||
error = 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( error )
|
||||
{
|
||||
wchar_t *colon;
|
||||
|
||||
sb_printf( sb_err,
|
||||
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_ERROR),
|
||||
L"set",
|
||||
dir,
|
||||
L"set",
|
||||
dir,
|
||||
key );
|
||||
|
||||
|
||||
colon = wcschr( dir, L':' );
|
||||
|
||||
if( colon && *(colon+1) )
|
||||
|
||||
if( colon && *(colon+1) )
|
||||
{
|
||||
show_hint = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( show_perror )
|
||||
{
|
||||
builtin_wperror( L"set" );
|
||||
}
|
||||
|
||||
|
||||
if( show_hint )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_HINT),
|
||||
L"set",
|
||||
key,
|
||||
key,
|
||||
wcschr( dir, L':' )+1);
|
||||
}
|
||||
|
||||
|
||||
if( error )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
sb_init( &sb );
|
||||
|
@ -148,9 +148,9 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
|||
}
|
||||
}
|
||||
val_str = (wchar_t *)sb.buff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch( env_set( key, val_str, scope | ENV_USER ) )
|
||||
{
|
||||
case ENV_PERM:
|
||||
|
@ -159,7 +159,7 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
|||
retcode=1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ENV_INVALID:
|
||||
{
|
||||
sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" );
|
||||
|
@ -173,13 +173,13 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
|||
return retcode;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
Extract indexes from a destination argument of the form name[index1 index2...]
|
||||
|
||||
\param indexes the list to insert the new indexes into
|
||||
\param src the source string to parse
|
||||
\param name the name of the element. Return null if the name in \c src does not match this name
|
||||
\param var_count the number of elements in the array to parse.
|
||||
\param var_count the number of elements in the array to parse.
|
||||
|
||||
\return the total number of indexes parsed, or -1 on error
|
||||
*/
|
||||
|
@ -188,58 +188,58 @@ static int parse_index( array_list_t *indexes,
|
|||
const wchar_t *name,
|
||||
int var_count )
|
||||
{
|
||||
int len;
|
||||
|
||||
size_t len;
|
||||
|
||||
int count = 0;
|
||||
const wchar_t *src_orig = src;
|
||||
|
||||
|
||||
if (src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
|
||||
{
|
||||
src++;
|
||||
}
|
||||
|
||||
|
||||
if (*src != L'[')
|
||||
{
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
len = src-src_orig;
|
||||
|
||||
|
||||
if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
|
||||
L"set",
|
||||
L"set",
|
||||
name,
|
||||
len,
|
||||
src_orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
src++;
|
||||
src++;
|
||||
|
||||
while (iswspace(*src))
|
||||
while (iswspace(*src))
|
||||
{
|
||||
src++;
|
||||
}
|
||||
|
||||
while (*src != L']')
|
||||
|
||||
while (*src != L']')
|
||||
{
|
||||
wchar_t *end;
|
||||
|
||||
|
||||
long l_ind;
|
||||
|
||||
errno = 0;
|
||||
|
||||
|
||||
l_ind = wcstol(src, &end, 10);
|
||||
|
||||
if( end==src || errno )
|
||||
|
||||
if( end==src || errno )
|
||||
{
|
||||
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
|
||||
return 0;
|
||||
|
@ -249,7 +249,7 @@ static int parse_index( array_list_t *indexes,
|
|||
{
|
||||
l_ind = var_count+l_ind+1;
|
||||
}
|
||||
|
||||
|
||||
al_push_long(indexes, l_ind);
|
||||
src = end;
|
||||
count++;
|
||||
|
@ -268,30 +268,30 @@ static int parse_index( array_list_t *indexes,
|
|||
|
||||
\return 0 if the operation was successfull, non-zero otherwise
|
||||
*/
|
||||
static int update_values( array_list_t *list,
|
||||
static int update_values( array_list_t *list,
|
||||
array_list_t *indexes,
|
||||
array_list_t *values )
|
||||
array_list_t *values )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Replace values where needed */
|
||||
for( i = 0; i < al_get_count(indexes); i++ )
|
||||
for( i = 0; i < al_get_count(indexes); i++ )
|
||||
{
|
||||
/*
|
||||
The '- 1' below is because the indices in fish are
|
||||
one-based, but the array_list_t uses zero-based indices
|
||||
*/
|
||||
long ind = al_get_long(indexes, i) - 1;
|
||||
void *new = (void *) al_get(values, i);
|
||||
const wchar_t *newv = (const wchar_t*) al_get(values, i);
|
||||
if( ind < 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
free((void *) al_get(list, ind));
|
||||
al_set(list, ind, new != 0 ? wcsdup(new) : wcsdup(L""));
|
||||
al_set(list, ind, newv != 0 ? wcsdup(newv) : wcsdup(L""));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -305,42 +305,42 @@ static int al_contains_long( array_list_t *list,
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
long current = al_get_long(list, i);
|
||||
if( current != 0 && current == val )
|
||||
if( current != 0 && current == val )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Erase from a list values at specified indexes
|
||||
Erase from a list values at specified indexes
|
||||
*/
|
||||
static void erase_values(array_list_t *list, array_list_t *indexes)
|
||||
static void erase_values(array_list_t *list, array_list_t *indexes)
|
||||
{
|
||||
long i;
|
||||
array_list_t result;
|
||||
|
||||
al_init(&result);
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
if (!al_contains_long(indexes, i + 1))
|
||||
if (!al_contains_long(indexes, i + 1))
|
||||
{
|
||||
al_push(&result, al_get(list, i));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
free( (void *)al_get(list, i));
|
||||
}
|
||||
}
|
||||
|
||||
al_truncate(list,0);
|
||||
|
||||
al_truncate(list,0);
|
||||
al_push_all( list, &result );
|
||||
al_destroy(&result);
|
||||
}
|
||||
|
@ -350,31 +350,31 @@ static void erase_values(array_list_t *list, array_list_t *indexes)
|
|||
Print the names of all environment variables in the scope, with or without values,
|
||||
with or without escaping
|
||||
*/
|
||||
static void print_variables(int include_values, int esc, int scope)
|
||||
static void print_variables(int include_values, int esc, int scope)
|
||||
{
|
||||
array_list_t names;
|
||||
int i;
|
||||
|
||||
|
||||
al_init( &names );
|
||||
env_get_names( &names, scope );
|
||||
|
||||
|
||||
sort_list( &names );
|
||||
|
||||
|
||||
for( i = 0; i < al_get_count(&names); i++ )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)al_get( &names, i );
|
||||
wchar_t *e_key = esc ? escape(key, 0) : wcsdup(key);
|
||||
|
||||
sb_append(sb_out, e_key);
|
||||
|
||||
if( include_values )
|
||||
|
||||
if( include_values )
|
||||
{
|
||||
wchar_t *value = env_get(key);
|
||||
wchar_t *e_value;
|
||||
if( value )
|
||||
{
|
||||
int shorten = 0;
|
||||
|
||||
|
||||
if( wcslen( value ) > 64 )
|
||||
{
|
||||
shorten = 1;
|
||||
|
@ -384,12 +384,12 @@ static void print_variables(int include_values, int esc, int scope)
|
|||
DIE_MEM();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
e_value = esc ? expand_escape_variable(value) : wcsdup(value);
|
||||
|
||||
sb_append(sb_out, L" ", e_value, (void *)0);
|
||||
|
||||
sb_append(sb_out, L" ", e_value, NULL);
|
||||
free(e_value);
|
||||
|
||||
|
||||
if( shorten )
|
||||
{
|
||||
sb_append(sb_out, L"\u2026");
|
||||
|
@ -398,7 +398,7 @@ static void print_variables(int include_values, int esc, int scope)
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sb_append(sb_out, L"\n");
|
||||
free(e_key);
|
||||
}
|
||||
|
@ -411,57 +411,57 @@ static void print_variables(int include_values, int esc, int scope)
|
|||
The set builtin. Creates, updates and erases environment variables
|
||||
and environemnt variable arrays.
|
||||
*/
|
||||
static int builtin_set( wchar_t **argv )
|
||||
static int builtin_set( wchar_t **argv )
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
Variables used for parsing the argument list
|
||||
*/
|
||||
static const struct woption
|
||||
long_options[] =
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"export", no_argument, 0, 'x'
|
||||
{
|
||||
L"export", no_argument, 0, 'x'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"global", no_argument, 0, 'g'
|
||||
{
|
||||
L"global", no_argument, 0, 'g'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"local", no_argument, 0, 'l'
|
||||
{
|
||||
L"local", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"names", no_argument, 0, 'n'
|
||||
}
|
||||
{
|
||||
L"names", no_argument, 0, 'n'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"unexport", no_argument, 0, 'u'
|
||||
}
|
||||
{
|
||||
L"unexport", no_argument, 0, 'u'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"universal", no_argument, 0, 'U'
|
||||
}
|
||||
{
|
||||
L"universal", no_argument, 0, 'U'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"query", no_argument, 0, 'q'
|
||||
}
|
||||
{
|
||||
L"query", no_argument, 0, 'q'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
const wchar_t *short_options = L"+xglenuUqh";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
@ -469,10 +469,10 @@ static int builtin_set( wchar_t **argv )
|
|||
/*
|
||||
Flags to set the work mode
|
||||
*/
|
||||
int local = 0, global = 0, export = 0;
|
||||
int local = 0, global = 0, exportv = 0;
|
||||
int erase = 0, list = 0, unexport=0;
|
||||
int universal = 0, query=0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Variables used for performing the actual work
|
||||
|
@ -482,22 +482,22 @@ static int builtin_set( wchar_t **argv )
|
|||
int scope;
|
||||
int slice=0;
|
||||
int i;
|
||||
|
||||
|
||||
wchar_t *bad_char;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parse options to obtain the requested operation and the modifiers */
|
||||
woptind = 0;
|
||||
while (1)
|
||||
while (1)
|
||||
{
|
||||
int c = wgetopt_long(argc, argv, short_options, long_options, 0);
|
||||
|
||||
if (c == -1)
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch(c)
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
@ -511,7 +511,7 @@ static int builtin_set( wchar_t **argv )
|
|||
break;
|
||||
|
||||
case 'x':
|
||||
export = 1;
|
||||
exportv = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
@ -556,23 +556,23 @@ static int builtin_set( wchar_t **argv )
|
|||
also specify scope
|
||||
*/
|
||||
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
if( query && (erase || list || global || local || universal || exportv || unexport ) )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We can't both list and erase varaibles */
|
||||
if( erase && list )
|
||||
if( erase && list )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
@ -581,7 +581,7 @@ static int builtin_set( wchar_t **argv )
|
|||
/*
|
||||
Variables can only have one scope
|
||||
*/
|
||||
if( local + global + universal > 1 )
|
||||
if( local + global + universal > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_GLOCAL,
|
||||
|
@ -593,7 +593,7 @@ static int builtin_set( wchar_t **argv )
|
|||
/*
|
||||
Variables can only have one export status
|
||||
*/
|
||||
if( export && unexport )
|
||||
if( exportv && unexport )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_EXPUNEXP,
|
||||
|
@ -605,7 +605,7 @@ static int builtin_set( wchar_t **argv )
|
|||
/*
|
||||
Calculate the scope value for variable assignement
|
||||
*/
|
||||
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (exportv ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
|
||||
if( query )
|
||||
{
|
||||
|
@ -621,7 +621,7 @@ static int builtin_set( wchar_t **argv )
|
|||
|
||||
if( !(dest = wcsdup(arg)))
|
||||
{
|
||||
DIE_MEM();
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
if( wcschr( dest, L'[' ) )
|
||||
|
@ -629,18 +629,18 @@ static int builtin_set( wchar_t **argv )
|
|||
slice = 1;
|
||||
*wcschr( dest, L'[' )=0;
|
||||
}
|
||||
|
||||
|
||||
if( slice )
|
||||
{
|
||||
array_list_t indexes;
|
||||
array_list_t result;
|
||||
int j;
|
||||
|
||||
|
||||
al_init( &result );
|
||||
al_init( &indexes );
|
||||
|
||||
tokenize_variable_array( env_get( dest ), &result );
|
||||
|
||||
|
||||
if( !parse_index( &indexes, arg, dest, al_get_count( &result ) ) )
|
||||
{
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
@ -663,32 +663,32 @@ static int builtin_set( wchar_t **argv )
|
|||
retcode++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( dest );
|
||||
|
||||
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if( list )
|
||||
|
||||
if( list )
|
||||
{
|
||||
/* Maybe we should issue an error if there are any other arguments? */
|
||||
print_variables(0, 0, scope);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( woptind == argc )
|
||||
{
|
||||
/*
|
||||
Print values of variables
|
||||
*/
|
||||
|
||||
if( erase )
|
||||
if( erase )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
|
@ -696,13 +696,13 @@ static int builtin_set( wchar_t **argv )
|
|||
{
|
||||
print_variables( 1, 1, scope );
|
||||
}
|
||||
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if( !(dest = wcsdup(argv[woptind])))
|
||||
{
|
||||
DIE_MEM();
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
if( wcschr( dest, L'[' ) )
|
||||
|
@ -710,7 +710,7 @@ static int builtin_set( wchar_t **argv )
|
|||
slice = 1;
|
||||
*wcschr( dest, L'[' )=0;
|
||||
}
|
||||
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
|
@ -718,7 +718,7 @@ static int builtin_set( wchar_t **argv )
|
|||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( (bad_char = wcsvarname( dest ) ) )
|
||||
{
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *bad_char );
|
||||
|
@ -726,7 +726,7 @@ static int builtin_set( wchar_t **argv )
|
|||
free( dest );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( slice && erase && (scope != ENV_USER) )
|
||||
{
|
||||
free( dest );
|
||||
|
@ -734,12 +734,12 @@ static int builtin_set( wchar_t **argv )
|
|||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set assignment can work in two modes, either using slices or
|
||||
using the whole array. We detect which mode is used here.
|
||||
*/
|
||||
|
||||
|
||||
if( slice )
|
||||
{
|
||||
|
||||
|
@ -750,22 +750,22 @@ static int builtin_set( wchar_t **argv )
|
|||
array_list_t values;
|
||||
array_list_t indexes;
|
||||
array_list_t result;
|
||||
|
||||
|
||||
al_init(&values);
|
||||
al_init(&indexes);
|
||||
al_init(&result);
|
||||
|
||||
|
||||
tokenize_variable_array( env_get(dest), &result );
|
||||
|
||||
|
||||
for( ; woptind<argc; woptind++ )
|
||||
{
|
||||
{
|
||||
if( !parse_index( &indexes, argv[woptind], dest, al_get_count( &result ) ) )
|
||||
{
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
val_count = argc-woptind-1;
|
||||
idx_count = al_get_count( &indexes );
|
||||
|
||||
|
@ -784,7 +784,7 @@ static int builtin_set( wchar_t **argv )
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
|
@ -802,12 +802,12 @@ static int builtin_set( wchar_t **argv )
|
|||
array_list_t value;
|
||||
al_init(&value);
|
||||
|
||||
while( woptind < argc )
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&value, argv[woptind++]);
|
||||
}
|
||||
|
||||
if( update_values( &result,
|
||||
if( update_values( &result,
|
||||
&indexes,
|
||||
&value ) )
|
||||
{
|
||||
|
@ -815,14 +815,14 @@ static int builtin_set( wchar_t **argv )
|
|||
sb_printf( sb_err, ARRAY_BOUNDS_ERR );
|
||||
sb_append( sb_err, L"\n" );
|
||||
}
|
||||
|
||||
|
||||
my_env_set(dest,
|
||||
&result,
|
||||
scope);
|
||||
|
||||
|
||||
al_destroy( &value );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &result, &free );
|
||||
|
@ -830,12 +830,12 @@ static int builtin_set( wchar_t **argv )
|
|||
|
||||
al_destroy(&indexes);
|
||||
al_destroy(&values);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
woptind++;
|
||||
|
||||
|
||||
/*
|
||||
No slicing
|
||||
*/
|
||||
|
@ -843,7 +843,7 @@ static int builtin_set( wchar_t **argv )
|
|||
{
|
||||
if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Values cannot be specfied with erase\n"),
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
@ -858,21 +858,21 @@ static int builtin_set( wchar_t **argv )
|
|||
{
|
||||
array_list_t val;
|
||||
al_init( &val );
|
||||
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
al_push( &val, argv[i] );
|
||||
}
|
||||
|
||||
retcode = my_env_set( dest, &val, scope );
|
||||
|
||||
al_destroy( &val );
|
||||
|
||||
}
|
||||
|
||||
al_destroy( &val );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( dest );
|
||||
|
||||
|
||||
return retcode;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/** \file builtin_ulimit.c Functions defining the ulimit builtin
|
||||
|
||||
Functions used for implementing the ulimit builtin.
|
||||
Functions used for implementing the ulimit builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
@ -38,11 +38,11 @@ struct resource_t
|
|||
/**
|
||||
Switch used on commandline to specify resource
|
||||
*/
|
||||
wchar_t switch_char;
|
||||
wchar_t switch_char;
|
||||
/**
|
||||
The implicit multiplier used when setting getting values
|
||||
*/
|
||||
int multiplier;
|
||||
int multiplier;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -96,7 +96,7 @@ static const struct resource_t resource_arr[] =
|
|||
#ifdef RLIMIT_AS
|
||||
{
|
||||
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
|
||||
}
|
||||
}
|
||||
,
|
||||
#endif
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ static const struct resource_t resource_arr[] =
|
|||
static int get_multiplier( int what )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; resource_arr[i].desc; i++ )
|
||||
{
|
||||
if( resource_arr[i].resource == what )
|
||||
|
@ -130,9 +130,9 @@ static int get_multiplier( int what )
|
|||
static rlim_t get( int resource, int hard )
|
||||
{
|
||||
struct rlimit ls;
|
||||
|
||||
|
||||
getrlimit( resource, &ls );
|
||||
|
||||
|
||||
return hard ? ls.rlim_max:ls.rlim_cur;
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ static void print( int resource, int hard )
|
|||
sb_append( sb_out, L"unlimited\n" );
|
||||
else
|
||||
sb_printf( sb_out, L"%d\n", l / get_multiplier( resource ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,12 +157,12 @@ static void print_all( int hard )
|
|||
{
|
||||
int i;
|
||||
int w=0;
|
||||
|
||||
|
||||
for( i=0; resource_arr[i].desc; i++ )
|
||||
{
|
||||
w=maxi( w, my_wcswidth(resource_arr[i].desc));
|
||||
}
|
||||
|
||||
|
||||
for( i=0; resource_arr[i].desc; i++ )
|
||||
{
|
||||
struct rlimit ls;
|
||||
|
@ -170,15 +170,15 @@ static void print_all( int hard )
|
|||
getrlimit( resource_arr[i].resource, &ls );
|
||||
l = hard ? ls.rlim_max:ls.rlim_cur;
|
||||
|
||||
wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, "));
|
||||
|
||||
const wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, "));
|
||||
|
||||
sb_printf( sb_out,
|
||||
L"%-*ls %10ls-%lc) ",
|
||||
w,
|
||||
resource_arr[i].desc,
|
||||
L"%-*ls %10ls-%lc) ",
|
||||
w,
|
||||
resource_arr[i].desc,
|
||||
unit,
|
||||
resource_arr[i].switch_char);
|
||||
|
||||
|
||||
if( l == RLIM_INFINITY )
|
||||
{
|
||||
sb_append( sb_out, L"unlimited\n" );
|
||||
|
@ -188,7 +188,7 @@ static void print_all( int hard )
|
|||
sb_printf( sb_out, L"%d\n", l/get_multiplier(resource_arr[i].resource) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +197,7 @@ static void print_all( int hard )
|
|||
static const wchar_t *get_desc( int what )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; resource_arr[i].desc; i++ )
|
||||
{
|
||||
if( resource_arr[i].resource == what )
|
||||
|
@ -217,26 +217,26 @@ static int set( int resource, int hard, int soft, rlim_t value )
|
|||
{
|
||||
struct rlimit ls;
|
||||
getrlimit( resource, &ls );
|
||||
|
||||
|
||||
if( hard )
|
||||
{
|
||||
ls.rlim_max = value;
|
||||
}
|
||||
|
||||
|
||||
if( soft )
|
||||
{
|
||||
ls.rlim_cur = value;
|
||||
|
||||
|
||||
/*
|
||||
Do not attempt to set the soft limit higher than the hard limit
|
||||
*/
|
||||
if( ( value == RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY ) ||
|
||||
if( ( value == RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY ) ||
|
||||
( value != RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY && value > ls.rlim_max))
|
||||
{
|
||||
ls.rlim_cur = ls.rlim_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( setrlimit( resource, &ls ) )
|
||||
{
|
||||
if( errno == EPERM )
|
||||
|
@ -244,8 +244,8 @@ static int set( int resource, int hard, int soft, rlim_t value )
|
|||
else
|
||||
builtin_wperror( L"ulimit" );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,14 +256,14 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
{
|
||||
int hard=0;
|
||||
int soft=0;
|
||||
|
||||
|
||||
int what = RLIMIT_FSIZE;
|
||||
int report_all = 0;
|
||||
|
||||
int argc = builtin_count_args( argv );
|
||||
|
||||
|
||||
woptind=0;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
static const struct woption
|
||||
|
@ -321,27 +321,27 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
L"virtual-memory-size", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aHScdflmnstuvh",
|
||||
long_options,
|
||||
argv,
|
||||
L"aHScdflmnstuvh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
|
@ -354,7 +354,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
case L'a':
|
||||
report_all=1;
|
||||
break;
|
||||
|
@ -364,17 +364,17 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
break;
|
||||
|
||||
case L'S':
|
||||
soft=1;
|
||||
soft=1;
|
||||
break;
|
||||
|
||||
case L'c':
|
||||
what=RLIMIT_CORE;
|
||||
break;
|
||||
|
||||
|
||||
case L'd':
|
||||
what=RLIMIT_DATA;
|
||||
break;
|
||||
|
||||
|
||||
case L'f':
|
||||
what=RLIMIT_FSIZE;
|
||||
break;
|
||||
|
@ -384,45 +384,45 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_RSS
|
||||
#ifdef RLIMIT_RSS
|
||||
case L'm':
|
||||
what=RLIMIT_RSS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case L'n':
|
||||
what=RLIMIT_NOFILE;
|
||||
break;
|
||||
|
||||
|
||||
case L's':
|
||||
what=RLIMIT_STACK;
|
||||
break;
|
||||
|
||||
|
||||
case L't':
|
||||
what=RLIMIT_CPU;
|
||||
break;
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
case L'u':
|
||||
what=RLIMIT_NPROC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_AS
|
||||
|
||||
#ifdef RLIMIT_AS
|
||||
case L'v':
|
||||
what=RLIMIT_AS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case L'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( report_all )
|
||||
{
|
||||
|
@ -435,14 +435,14 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
sb_append( sb_err,
|
||||
argv[0],
|
||||
L": Too many arguments\n",
|
||||
(void *)0 );
|
||||
NULL );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch( argc - woptind )
|
||||
{
|
||||
case 0:
|
||||
|
@ -453,7 +453,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
print( what, hard );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
/*
|
||||
|
@ -469,7 +469,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
{
|
||||
hard=soft=1;
|
||||
}
|
||||
|
||||
|
||||
if( wcscasecmp( argv[woptind], L"unlimited" )==0)
|
||||
{
|
||||
new_limit = RLIM_INFINITY;
|
||||
|
@ -484,33 +484,33 @@ static int builtin_ulimit( wchar_t ** argv )
|
|||
}
|
||||
else
|
||||
{
|
||||
errno=0;
|
||||
errno=0;
|
||||
new_limit = wcstol( argv[woptind], &end, 10 );
|
||||
if( errno || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Invalid limit '%ls'\n",
|
||||
argv[0],
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Invalid limit '%ls'\n",
|
||||
argv[0],
|
||||
argv[woptind] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
new_limit *= get_multiplier( what );
|
||||
}
|
||||
|
||||
|
||||
return set( what, hard, soft, new_limit );
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
sb_append( sb_err,
|
||||
argv[0],
|
||||
L": Too many arguments\n",
|
||||
(void *)0 );
|
||||
NULL );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
577
common.cpp
577
common.cpp
File diff suppressed because it is too large
Load diff
149
common.h
149
common.h
|
@ -12,9 +12,16 @@
|
|||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <termios.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <errno.h>
|
||||
#include "util.h"
|
||||
|
||||
/* Common string type */
|
||||
typedef std::wstring wcstring;
|
||||
|
||||
/**
|
||||
Maximum number of bytes used by a single utf-8 character
|
||||
*/
|
||||
|
@ -59,11 +66,15 @@
|
|||
*/
|
||||
#define ESCAPE_NO_QUOTED 2
|
||||
|
||||
|
||||
/**
|
||||
Helper macro for errors
|
||||
*/
|
||||
#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0)
|
||||
|
||||
/**
|
||||
Save the shell mode on startup so we can restore them on exit
|
||||
*/
|
||||
extern struct termios shell_modes;
|
||||
extern struct termios shell_modes;
|
||||
|
||||
/**
|
||||
The character to use where the text has been truncated. Is an
|
||||
|
@ -86,7 +97,7 @@ extern char *profile;
|
|||
Name of the current program. Should be set at startup. Used by the
|
||||
debug function.
|
||||
*/
|
||||
extern wchar_t *program_name;
|
||||
extern const wchar_t *program_name;
|
||||
|
||||
/**
|
||||
This macro is used to check that an input argument is not null. It
|
||||
|
@ -116,7 +127,7 @@ extern wchar_t *program_name;
|
|||
exit_read_count=read( 0, &exit_read_buff, 1 ); \
|
||||
exit( 1 ); \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Exit program at once, leaving an error message about running out of memory.
|
||||
|
@ -144,26 +155,26 @@ extern wchar_t *program_name;
|
|||
show_stackframe(); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Shorthand for wgettext call
|
||||
*/
|
||||
#define _(wstr) wgettext(wstr)
|
||||
#define _(wstr) wgettext((const wchar_t *)wstr)
|
||||
|
||||
/**
|
||||
Noop, used to tell xgettext that a string should be translated,
|
||||
even though it is not directly sent to wgettext.
|
||||
even though it is not directly sent to wgettext.
|
||||
*/
|
||||
#define N_(wstr) wstr
|
||||
|
||||
/**
|
||||
Check if the specified stringelement is a part of the specified string list
|
||||
*/
|
||||
#define contains( str,... ) contains_internal( str, __VA_ARGS__, (void *)0 )
|
||||
#define contains( str,... ) contains_internal( str, __VA_ARGS__, NULL )
|
||||
/**
|
||||
Concatenate all the specified strings into a single newly allocated one
|
||||
*/
|
||||
#define wcsdupcat( str,... ) wcsdupcat_internal( str, __VA_ARGS__, (void *)0 )
|
||||
#define wcsdupcat( str,... ) wcsdupcat_internal( str, __VA_ARGS__, NULL )
|
||||
|
||||
/**
|
||||
Print a stack trace to stderr
|
||||
|
@ -181,7 +192,7 @@ wchar_t **list_to_char_arr( array_list_t *l );
|
|||
Read a line from the stream f into the buffer buff of length len. If
|
||||
buff is to small, it will be reallocated, and both buff and len will
|
||||
be updated to reflect this. Returns the number of bytes read or -1
|
||||
on failiure.
|
||||
on failiure.
|
||||
|
||||
If the carriage return character is encountered, it is
|
||||
ignored. fgetws() considers the line to end if reading the file
|
||||
|
@ -196,6 +207,8 @@ int fgetws2( wchar_t **buff, int *len, FILE *f );
|
|||
*/
|
||||
void sort_list( array_list_t *comp );
|
||||
|
||||
void sort_strings( std::vector<wcstring> &strings);
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string equivalent of the
|
||||
specified multibyte character string
|
||||
|
@ -205,6 +218,15 @@ void sort_list( array_list_t *comp );
|
|||
*/
|
||||
wchar_t *str2wcs( const char *in );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string equivalent of the
|
||||
specified multibyte character string
|
||||
|
||||
This function encodes illegal character sequences in a reversible
|
||||
way using the private use area.
|
||||
*/
|
||||
wcstring str2wcstring( const char *in );
|
||||
|
||||
/**
|
||||
Converts the narrow character string \c in into it's wide
|
||||
equivalent, stored in \c out. \c out must have enough space to fit
|
||||
|
@ -223,6 +245,16 @@ wchar_t *str2wcs_internal( const char *in, wchar_t *out );
|
|||
way using the private use area.
|
||||
*/
|
||||
char *wcs2str( const wchar_t *in );
|
||||
std::string wcs2string(const wcstring &input);
|
||||
|
||||
void assert_is_main_thread(const char *who);
|
||||
#define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x)
|
||||
#define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__)
|
||||
|
||||
void assert_is_background_thread(const char *who);
|
||||
#define ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(x) assert_is_background_thread(x)
|
||||
#define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__)
|
||||
|
||||
|
||||
/**
|
||||
Converts the wide character string \c in into it's narrow
|
||||
|
@ -234,6 +266,67 @@ char *wcs2str( const wchar_t *in );
|
|||
*/
|
||||
char *wcs2str_internal( const wchar_t *in, char *out );
|
||||
|
||||
/**
|
||||
Converts some type to a wstring.
|
||||
*/
|
||||
template<typename T>
|
||||
wcstring format_val(T x) {
|
||||
std::wstringstream stream;
|
||||
stream << x;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T from_string(const wcstring &x) {
|
||||
T result;
|
||||
std::wstringstream stream(x);
|
||||
stream >> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
class scoped_lock {
|
||||
pthread_mutex_t *lock;
|
||||
public:
|
||||
scoped_lock(pthread_mutex_t &mutex) : lock(&mutex) {
|
||||
VOMIT_ON_FAILURE(pthread_mutex_lock(lock));
|
||||
}
|
||||
|
||||
~scoped_lock() {
|
||||
VOMIT_ON_FAILURE(pthread_mutex_unlock(lock));
|
||||
}
|
||||
};
|
||||
|
||||
class wcstokenizer {
|
||||
wchar_t *buffer, *str, *state;
|
||||
const wcstring sep;
|
||||
|
||||
public:
|
||||
wcstokenizer(const wcstring &s, const wcstring &separator) : sep(separator) {
|
||||
wchar_t *wcsdup(const wchar_t *s);
|
||||
buffer = wcsdup(s.c_str());
|
||||
str = buffer;
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
bool next(wcstring &result) {
|
||||
wchar_t *tmp = wcstok(str, sep.c_str(), &state);
|
||||
str = NULL;
|
||||
if (tmp) result = tmp;
|
||||
return tmp != NULL;
|
||||
}
|
||||
|
||||
~wcstokenizer() {
|
||||
free(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Appends a path component, with a / if necessary
|
||||
*/
|
||||
void append_path_component(wcstring &path, const wcstring &component);
|
||||
|
||||
wcstring format_string(const wchar_t *format, ...);
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string array equivalent of
|
||||
the specified multibyte character string array
|
||||
|
@ -258,7 +351,7 @@ __sentinel wchar_t *wcsdupcat_internal( const wchar_t *a, ... );
|
|||
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name.
|
||||
Test if the given string is a valid variable name.
|
||||
|
||||
\return null if this is a valid name, and a pointer to the first invalid character otherwise
|
||||
*/
|
||||
|
@ -267,7 +360,7 @@ wchar_t *wcsvarname( const wchar_t *str );
|
|||
|
||||
|
||||
/**
|
||||
Test if the given string is a valid function name.
|
||||
Test if the given string is a valid function name.
|
||||
|
||||
\return null if this is a valid name, and a pointer to the first invalid character otherwise
|
||||
*/
|
||||
|
@ -275,7 +368,7 @@ wchar_t *wcsvarname( const wchar_t *str );
|
|||
wchar_t *wcsfuncname( const wchar_t *str );
|
||||
|
||||
/**
|
||||
Test if the given string is valid in a variable name
|
||||
Test if the given string is valid in a variable name
|
||||
|
||||
\return 1 if this is a valid name, 0 otherwise
|
||||
*/
|
||||
|
@ -311,14 +404,14 @@ void error_reset();
|
|||
This function behaves exactly like a wide character equivalent of
|
||||
the C function setlocale, except that it will also try to detect if
|
||||
the user is using a Unicode character set, and if so, use the
|
||||
unicode ellipsis character as ellipsis, instead of '$'.
|
||||
unicode ellipsis character as ellipsis, instead of '$'.
|
||||
*/
|
||||
const wchar_t *wsetlocale( int category, const wchar_t *locale );
|
||||
|
||||
/**
|
||||
Checks if \c needle is included in the list of strings specified. A warning is printed if needle is zero.
|
||||
|
||||
\param needle the string to search for in the list
|
||||
\param needle the string to search for in the list
|
||||
|
||||
\return zero if needle is not found, of if needle is null, non-zero otherwise
|
||||
*/
|
||||
|
@ -346,9 +439,9 @@ ssize_t write_loop(int fd, char *buff, size_t count);
|
|||
Because debug is often called to tell the user about an error,
|
||||
before using wperror to give a specific error message, debug will
|
||||
never ever modify the value of errno.
|
||||
|
||||
|
||||
\param level the priority of the message. Lower number means higher priority. Messages with a priority_number higher than \c debug_level will be ignored..
|
||||
\param msg the message format string.
|
||||
\param msg the message format string.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -360,7 +453,7 @@ void debug( int level, const wchar_t *msg, ... );
|
|||
|
||||
/**
|
||||
Replace special characters with backslash escape sequences. Newline is
|
||||
replaced with \n, etc.
|
||||
replaced with \n, etc.
|
||||
|
||||
\param in The string to be escaped
|
||||
\param escape_all Whether all characters wich hold special meaning in fish (Pipe, semicolon, etc,) should be escaped, or only unprintable characters
|
||||
|
@ -368,6 +461,7 @@ void debug( int level, const wchar_t *msg, ... );
|
|||
*/
|
||||
|
||||
wchar_t *escape( const wchar_t *in, int escape_all );
|
||||
wcstring escape_string( const wcstring &in, int escape_all );
|
||||
|
||||
/**
|
||||
Expand backslashed escapes and substitute them with their unescaped
|
||||
|
@ -380,21 +474,24 @@ wchar_t *escape( const wchar_t *in, int escape_all );
|
|||
an invalid sequence is specified, 0 is returned.
|
||||
|
||||
*/
|
||||
wchar_t *unescape( const wchar_t * in,
|
||||
wchar_t *unescape( const wchar_t * in,
|
||||
int escape_special );
|
||||
|
||||
void unescape_string( wcstring &str,
|
||||
int escape_special );
|
||||
|
||||
/**
|
||||
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
|
||||
milliseconds between polls and timing out after timeout seconds,
|
||||
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
|
||||
milliseconds between polls and timing out after timeout seconds,
|
||||
thereafter forcibly attempting to obtain the lock if force is non-zero.
|
||||
Returns 1 on success, 0 on failure.
|
||||
To release the lock the lockfile must be unlinked.
|
||||
A unique temporary file named by appending characters to the lockfile name
|
||||
A unique temporary file named by appending characters to the lockfile name
|
||||
is used; any pre-existing file of the same name is subject to deletion.
|
||||
*/
|
||||
int acquire_lock_file( const char *lockfile, const int timeout, int force );
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns the width of the terminal window, so that not all
|
||||
functions that use these values continually have to keep track of
|
||||
it separately.
|
||||
|
@ -428,9 +525,9 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff );
|
|||
Tokenize the specified string into the specified array_list_t.
|
||||
Each new element is allocated using malloc and must be freed by the
|
||||
caller.
|
||||
|
||||
|
||||
\param val the input string. The contents of this string is not changed.
|
||||
\param out the list in which to place the elements.
|
||||
\param out the list in which to place the elements.
|
||||
*/
|
||||
void tokenize_variable_array( const wchar_t *val, array_list_t *out );
|
||||
|
||||
|
@ -440,7 +537,7 @@ void tokenize_variable_array( const wchar_t *val, array_list_t *out );
|
|||
|
||||
\return 0 if, at the time of function return the directory exists, -1 otherwise.
|
||||
*/
|
||||
int create_directory( wchar_t *d );
|
||||
int create_directory( const wchar_t *d );
|
||||
|
||||
/**
|
||||
Print a short message about how to file a bug report to stderr
|
||||
|
|
316
complete.cpp
316
complete.cpp
|
@ -124,7 +124,7 @@
|
|||
If either short_opt or long_opt are non-zero, they specify a switch
|
||||
for the command. If \c comp is also not empty, it contains a list
|
||||
of non-switch arguments that may only follow directly after the
|
||||
specified switch.
|
||||
specified switch.
|
||||
*/
|
||||
typedef struct complete_entry_opt
|
||||
{
|
||||
|
@ -192,7 +192,7 @@ void completion_allocate( array_list_t *context,
|
|||
const wchar_t *desc,
|
||||
int flags )
|
||||
{
|
||||
completion_t *res = halloc( context, sizeof( completion_t) );
|
||||
completion_t *res = (completion_t *)halloc( context, sizeof( completion_t) );
|
||||
res->completion = halloc_wcsdup( context, comp );
|
||||
if( desc )
|
||||
res->description = halloc_wcsdup( context, desc );
|
||||
|
@ -202,12 +202,12 @@ void completion_allocate( array_list_t *context,
|
|||
int len = wcslen(comp);
|
||||
|
||||
flags = flags & (~COMPLETE_AUTO_SPACE);
|
||||
|
||||
|
||||
if( ( len > 0 ) && ( wcschr( L"/=@:", comp[ len - 1 ] ) != 0 ) )
|
||||
flags |= COMPLETE_NO_SPACE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
res->flags = flags;
|
||||
al_push( context, res );
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ void completion_allocate( array_list_t *context,
|
|||
static void complete_destroy()
|
||||
{
|
||||
complete_entry_t *i=first_entry, *prev;
|
||||
|
||||
|
||||
while( i )
|
||||
{
|
||||
prev = i;
|
||||
|
@ -226,9 +226,9 @@ static void complete_destroy()
|
|||
complete_free_entry( prev );
|
||||
}
|
||||
first_entry = 0;
|
||||
|
||||
|
||||
parse_util_load_reset( L"fish_complete_path", 0 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -276,7 +276,7 @@ static int condition_test( const wchar_t *condition )
|
|||
|
||||
if( !condition_cache )
|
||||
{
|
||||
condition_cache = malloc( sizeof( hash_table_t ) );
|
||||
condition_cache = (hash_table_t *)malloc( sizeof( hash_table_t ) );
|
||||
if( !condition_cache )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
@ -302,7 +302,7 @@ static int condition_test( const wchar_t *condition )
|
|||
*/
|
||||
}
|
||||
|
||||
if( wcscmp( test_res, CC_TRUE ) == 0 )
|
||||
if( wcscmp( (const wchar_t *)test_res, CC_TRUE ) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ static void complete_free_opt_recursive( complete_entry_opt_t *o )
|
|||
{
|
||||
if( !o )
|
||||
return;
|
||||
|
||||
|
||||
complete_free_opt_recursive( o->next );
|
||||
halloc_free( o );
|
||||
}
|
||||
|
@ -365,11 +365,11 @@ static complete_entry_t *complete_get_exact_entry( const wchar_t *cmd,
|
|||
|
||||
if( c == 0 )
|
||||
{
|
||||
if( !(c = malloc( sizeof(complete_entry_t) )))
|
||||
if( !(c = (complete_entry_t *)malloc( sizeof(complete_entry_t) )))
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
|
||||
c->next = first_entry;
|
||||
first_entry = c;
|
||||
|
||||
|
@ -415,15 +415,15 @@ void complete_add( const wchar_t *cmd,
|
|||
|
||||
c = complete_get_exact_entry( cmd, cmd_type );
|
||||
|
||||
opt = halloc( 0, sizeof( complete_entry_opt_t ) );
|
||||
|
||||
opt = (complete_entry_opt_t *)halloc( 0, sizeof( complete_entry_opt_t ) );
|
||||
|
||||
opt->next = c->first_option;
|
||||
c->first_option = opt;
|
||||
if( short_opt != L'\0' )
|
||||
{
|
||||
int len = 1 + ((result_mode & NO_COMMON) != 0);
|
||||
c->short_opt_str =
|
||||
realloc( c->short_opt_str,
|
||||
(wchar_t *)realloc( c->short_opt_str,
|
||||
sizeof(wchar_t)*(wcslen( c->short_opt_str ) + 1 + len) );
|
||||
wcsncat( c->short_opt_str,
|
||||
&short_opt, 1 );
|
||||
|
@ -432,7 +432,7 @@ void complete_add( const wchar_t *cmd,
|
|||
wcscat( c->short_opt_str, L":" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
opt->short_opt = short_opt;
|
||||
opt->result_mode = result_mode;
|
||||
opt->old_mode=old_mode;
|
||||
|
@ -441,7 +441,7 @@ void complete_add( const wchar_t *cmd,
|
|||
opt->condition = condition?halloc_wcsdup(opt, condition):L"";
|
||||
opt->long_opt = long_opt?halloc_wcsdup(opt, long_opt):L"" ;
|
||||
opt->flags = flags;
|
||||
|
||||
|
||||
if( desc && wcslen( desc ) )
|
||||
{
|
||||
opt->desc = halloc_wcsdup( opt, desc );
|
||||
|
@ -450,7 +450,7 @@ void complete_add( const wchar_t *cmd,
|
|||
{
|
||||
opt->desc = L"";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,7 +463,7 @@ static complete_entry_t *complete_remove_entry( complete_entry_t *e,
|
|||
{
|
||||
|
||||
complete_entry_opt_t *o, *oprev=0, *onext=0;
|
||||
|
||||
|
||||
if(( short_opt == 0 ) && (long_opt == 0 ) )
|
||||
{
|
||||
complete_free_opt_recursive( e->first_option );
|
||||
|
@ -471,11 +471,11 @@ static complete_entry_t *complete_remove_entry( complete_entry_t *e,
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
for( o= e->first_option; o; o=onext )
|
||||
{
|
||||
onext=o->next;
|
||||
|
||||
|
||||
if( ( short_opt==o->short_opt ) ||
|
||||
( wcscmp( long_opt, o->long_opt ) == 0 ) )
|
||||
{
|
||||
|
@ -496,13 +496,13 @@ static complete_entry_t *complete_remove_entry( complete_entry_t *e,
|
|||
{
|
||||
pos2++;
|
||||
}
|
||||
|
||||
|
||||
memmove( pos,
|
||||
pos2,
|
||||
sizeof(wchar_t)*wcslen(pos2) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( oprev == 0 )
|
||||
{
|
||||
e->first_option = o->next;
|
||||
|
@ -519,14 +519,14 @@ static complete_entry_t *complete_remove_entry( complete_entry_t *e,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( e && (e->first_option == 0) )
|
||||
{
|
||||
free( e->short_opt_str );
|
||||
free( e );
|
||||
e=0;
|
||||
}
|
||||
|
||||
|
||||
return e;
|
||||
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ void complete_remove( const wchar_t *cmd,
|
|||
complete_entry_t *e, *eprev=0, *enext=0;
|
||||
|
||||
CHECK( cmd, );
|
||||
|
||||
|
||||
for( e = first_entry; e; e=enext )
|
||||
{
|
||||
enext=e->next;
|
||||
|
@ -566,7 +566,7 @@ void complete_remove( const wchar_t *cmd,
|
|||
first_entry = enext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +575,7 @@ void complete_remove( const wchar_t *cmd,
|
|||
pointers are allocated using halloc and will be free'd when\c
|
||||
context is halloc_free'd.
|
||||
*/
|
||||
static void parse_cmd_string( void *context,
|
||||
static void parse_cmd_string( void *context,
|
||||
const wchar_t *str,
|
||||
wchar_t **pathp,
|
||||
wchar_t **cmdp )
|
||||
|
@ -592,7 +592,7 @@ static void parse_cmd_string( void *context,
|
|||
*/
|
||||
path = halloc_wcsdup( context, L"");
|
||||
}
|
||||
|
||||
|
||||
/* Make sure the path is not included in the command */
|
||||
cmd = wcsrchr( str, L'/' );
|
||||
if( cmd != 0 )
|
||||
|
@ -603,7 +603,7 @@ static void parse_cmd_string( void *context,
|
|||
{
|
||||
cmd = (wchar_t *)str;
|
||||
}
|
||||
|
||||
|
||||
*pathp=path;
|
||||
*cmdp=cmd;
|
||||
}
|
||||
|
@ -627,10 +627,10 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
char *short_validated;
|
||||
|
||||
void *context;
|
||||
|
||||
|
||||
CHECK( str, 0 );
|
||||
CHECK( opt, 0 );
|
||||
|
||||
|
||||
/*
|
||||
Check some generic things like -- and - options.
|
||||
*/
|
||||
|
@ -642,7 +642,7 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
if( wcscmp( L"--", opt ) == 0 )
|
||||
|
@ -652,7 +652,7 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( opt[0] != L'-' )
|
||||
{
|
||||
if( errors )
|
||||
|
@ -664,11 +664,11 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
|
||||
context = halloc( 0, 0 );
|
||||
|
||||
if( !(short_validated = halloc( context, wcslen( opt ) )))
|
||||
if( !(short_validated = (char *)halloc( context, wcslen( opt ) )))
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
memset( short_validated, 0, wcslen( opt ) );
|
||||
|
@ -690,14 +690,14 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
gnu_opt_len = wcslen(opt)-2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parse_cmd_string( context, str, &path, &cmd );
|
||||
|
||||
/*
|
||||
Make sure completions are loaded for the specified command
|
||||
*/
|
||||
complete_load( cmd, 0 );
|
||||
|
||||
|
||||
for( i=first_entry; i; i=i->next )
|
||||
{
|
||||
wchar_t *match = i->cmd_type?path:cmd;
|
||||
|
@ -707,7 +707,7 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
found_match = 1;
|
||||
|
||||
if( !i->authoritative )
|
||||
|
@ -726,7 +726,7 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( wcsncmp( &opt[2], o->long_opt, gnu_opt_len )==0)
|
||||
{
|
||||
hash_put( &gnu_match_hash, o->long_opt, L"" );
|
||||
|
@ -845,7 +845,7 @@ int complete_is_valid_option( const wchar_t *str,
|
|||
hash_destroy( &gnu_match_hash );
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
|
||||
return (authoritative && found_match)?opt_found:1;
|
||||
}
|
||||
|
||||
|
@ -893,7 +893,7 @@ static void complete_strings( array_list_t *comp_out,
|
|||
|
||||
wc = parse_util_unescape_wildcards( tmp );
|
||||
free(tmp);
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( possible_comp ); i++ )
|
||||
{
|
||||
wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );
|
||||
|
@ -921,7 +921,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
hash_table_t lookup;
|
||||
wchar_t *esc;
|
||||
int skip;
|
||||
|
||||
|
||||
if( !cmd )
|
||||
return;
|
||||
|
||||
|
@ -948,24 +948,24 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
}
|
||||
|
||||
skip = 1;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( comp ); i++ )
|
||||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, i );
|
||||
|
||||
if( !wcslen( c->completion) || (c->completion[wcslen(c->completion)-1] != L'/' ))
|
||||
|
||||
if( !wcslen( c->completion) || (c->completion[wcslen(c->completion)-1] != L'/' ))
|
||||
{
|
||||
skip = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( skip )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esc = escape( cmd_start, 1 );
|
||||
|
||||
|
@ -985,7 +985,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
*/
|
||||
if( exec_subshell( lookup_cmd, &list ) != -1 )
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
Then discard anything that is not a possible completion and put
|
||||
the result into a hashtable with the completion as key and the
|
||||
|
@ -997,7 +997,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
{
|
||||
wchar_t *el = (wchar_t *)al_get( &list, i );
|
||||
wchar_t *key, *key_end, *val_begin;
|
||||
|
||||
|
||||
if( !el )
|
||||
continue;
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
|
||||
if( !key_end )
|
||||
continue;
|
||||
|
||||
|
||||
*key_end = 0;
|
||||
val_begin = key_end+1;
|
||||
|
||||
|
@ -1016,7 +1016,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
things.
|
||||
*/
|
||||
val_begin[0]=towupper(val_begin[0]);
|
||||
|
||||
|
||||
hash_put( &lookup, key, val_begin );
|
||||
}
|
||||
|
||||
|
@ -1031,19 +1031,19 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
|||
{
|
||||
completion_t *c = (completion_t *)al_get( comp, i );
|
||||
const wchar_t *el = c->completion;
|
||||
|
||||
|
||||
wchar_t *new_desc;
|
||||
|
||||
|
||||
new_desc = (wchar_t *)hash_get( &lookup,
|
||||
el );
|
||||
|
||||
|
||||
if( new_desc )
|
||||
{
|
||||
c->description = halloc_wcsdup( comp, new_desc );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hash_destroy( &lookup );
|
||||
al_foreach( &list,
|
||||
&free );
|
||||
|
@ -1095,7 +1095,7 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
|
||||
if( use_command )
|
||||
{
|
||||
|
||||
|
||||
if( expand_string( 0,
|
||||
wcsdup(cmd),
|
||||
comp,
|
||||
|
@ -1109,13 +1109,13 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
{
|
||||
if( use_command )
|
||||
{
|
||||
|
||||
|
||||
path = env_get(L"PATH");
|
||||
if( path )
|
||||
{
|
||||
|
||||
|
||||
path_cpy = wcsdup( path );
|
||||
|
||||
|
||||
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
|
||||
nxt_path != 0;
|
||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||
|
@ -1124,21 +1124,21 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
int i;
|
||||
int path_len = wcslen(nxt_path);
|
||||
int add_slash;
|
||||
|
||||
|
||||
if( !path_len )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
add_slash = nxt_path[path_len-1]!=L'/';
|
||||
nxt_completion = wcsdupcat( nxt_path,
|
||||
add_slash?L"/":L"",
|
||||
cmd );
|
||||
if( ! nxt_completion )
|
||||
continue;
|
||||
|
||||
|
||||
prev_count = al_get_count( comp );
|
||||
|
||||
|
||||
if( expand_string( 0,
|
||||
nxt_completion,
|
||||
comp,
|
||||
|
@ -1159,7 +1159,7 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
complete_cmd_desc( cmd, comp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
These return the original strings - don't free them
|
||||
*/
|
||||
|
@ -1173,7 +1173,7 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
}
|
||||
|
||||
al_truncate( &possible_comp, 0 );
|
||||
|
||||
|
||||
if( use_builtin )
|
||||
{
|
||||
builtin_get_names( &possible_comp );
|
||||
|
@ -1202,7 +1202,7 @@ static void complete_cmd( const wchar_t *cmd,
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( expand_string( 0,
|
||||
nxt_completion,
|
||||
comp,
|
||||
|
@ -1242,7 +1242,7 @@ static void complete_from_args( const wchar_t *str,
|
|||
proc_push_interactive(0);
|
||||
eval_args( args, &possible_comp );
|
||||
proc_pop_interactive();
|
||||
|
||||
|
||||
complete_strings( comp_out, str, desc, 0, &possible_comp, flags );
|
||||
|
||||
al_foreach( &possible_comp, &free );
|
||||
|
@ -1355,10 +1355,10 @@ static void complete_load_handler( const wchar_t *cmd )
|
|||
void complete_load( const wchar_t *name, int reload )
|
||||
{
|
||||
CHECK( name, );
|
||||
parse_util_load( name,
|
||||
parse_util_load( name,
|
||||
L"fish_complete_path",
|
||||
&complete_load_handler,
|
||||
reload );
|
||||
&complete_load_handler,
|
||||
reload );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1380,7 +1380,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
int use_common=1, use_files=1;
|
||||
|
||||
void *context = halloc( 0, 0 );
|
||||
|
||||
|
||||
parse_cmd_string( context, cmd_orig, &path, &cmd );
|
||||
|
||||
complete_load( cmd, 1 );
|
||||
|
@ -1395,11 +1395,11 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
use_common=1;
|
||||
if( use_switches )
|
||||
{
|
||||
|
||||
|
||||
if( str[0] == L'-' )
|
||||
{
|
||||
/* Check if we are entering a combined option and argument
|
||||
|
@ -1420,7 +1420,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
{
|
||||
/* Set to true if we found a matching old-style switch */
|
||||
int old_style_match = 0;
|
||||
|
||||
|
||||
/*
|
||||
If we are using old style long options, check for them
|
||||
first
|
||||
|
@ -1438,7 +1438,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
No old style option matched, or we are not using old
|
||||
style options. We check if any short (or gnu style
|
||||
|
@ -1467,7 +1467,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( use_common )
|
||||
{
|
||||
|
||||
|
@ -1487,7 +1487,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
use_files &= ((o->result_mode & NO_FILES )==0);
|
||||
complete_from_args( str, o->comp, C_(o->desc), comp_out, o->flags );
|
||||
}
|
||||
|
||||
|
||||
if( wcslen(str) > 0 && use_switches )
|
||||
{
|
||||
/*
|
||||
|
@ -1500,7 +1500,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
wchar_t completion[2];
|
||||
completion[0] = o->short_opt;
|
||||
completion[1] = 0;
|
||||
|
||||
|
||||
completion_allocate( comp_out, completion, desc, 0 );
|
||||
|
||||
}
|
||||
|
@ -1511,9 +1511,9 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
if( o->long_opt[0] != L'\0' )
|
||||
{
|
||||
int match=0, match_no_case=0;
|
||||
|
||||
|
||||
string_buffer_t *whole_opt = sb_halloc( context );
|
||||
sb_append( whole_opt, o->old_mode?L"-":L"--", o->long_opt, (void *)0 );
|
||||
sb_append( whole_opt, o->old_mode?L"-":L"--", o->long_opt, NULL );
|
||||
|
||||
match = wcsncmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0;
|
||||
|
||||
|
@ -1521,7 +1521,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
{
|
||||
match_no_case = wcsncasecmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0;
|
||||
}
|
||||
|
||||
|
||||
if( match || match_no_case )
|
||||
{
|
||||
int has_arg=0; /* Does this switch have any known arguments */
|
||||
|
@ -1530,7 +1530,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
int offset = 0;
|
||||
int flags = 0;
|
||||
|
||||
|
||||
|
||||
if( match )
|
||||
offset = wcslen( str );
|
||||
else
|
||||
|
@ -1541,7 +1541,7 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
|
||||
if( !o->old_mode && ( has_arg && !req_arg ) )
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
Optional arguments to a switch can
|
||||
only be handled using the '=', so we
|
||||
|
@ -1555,31 +1555,31 @@ static int complete_param( const wchar_t *cmd_orig,
|
|||
sb_init( &completion );
|
||||
|
||||
sb_printf( &completion,
|
||||
L"%ls=",
|
||||
L"%ls=",
|
||||
((wchar_t *)whole_opt->buff)+offset );
|
||||
|
||||
|
||||
completion_allocate( comp_out,
|
||||
(wchar_t *)completion.buff,
|
||||
C_(o->desc),
|
||||
flags );
|
||||
|
||||
flags );
|
||||
|
||||
sb_destroy( &completion );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
completion_allocate( comp_out,
|
||||
((wchar_t *)whole_opt->buff) + offset,
|
||||
C_(o->desc),
|
||||
flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
|
||||
return use_files;
|
||||
}
|
||||
|
||||
|
@ -1592,7 +1592,7 @@ static void complete_param_expand( wchar_t *str,
|
|||
{
|
||||
wchar_t *comp_str;
|
||||
int flags;
|
||||
|
||||
|
||||
if( (wcsncmp( str, L"--", 2 )) == 0 && (comp_str = wcschr(str, L'=' ) ) )
|
||||
{
|
||||
comp_str++;
|
||||
|
@ -1602,18 +1602,18 @@ static void complete_param_expand( wchar_t *str,
|
|||
comp_str = str;
|
||||
}
|
||||
|
||||
flags = EXPAND_SKIP_CMDSUBST |
|
||||
ACCEPT_INCOMPLETE |
|
||||
flags = EXPAND_SKIP_CMDSUBST |
|
||||
ACCEPT_INCOMPLETE |
|
||||
(do_file?0:EXPAND_SKIP_WILDCARDS);
|
||||
|
||||
if( expand_string( 0,
|
||||
|
||||
if( expand_string( 0,
|
||||
wcsdup(comp_str),
|
||||
comp_out,
|
||||
flags ) == EXPAND_ERROR )
|
||||
{
|
||||
debug( 3, L"Error while expanding string '%ls'", comp_str );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1636,13 +1636,13 @@ static int complete_variable( const wchar_t *whole_var,
|
|||
{
|
||||
wchar_t *name = (wchar_t *)al_get( &names, i );
|
||||
int namelen = wcslen( name );
|
||||
int match=0, match_no_case=0;
|
||||
int match=0, match_no_case=0;
|
||||
|
||||
if( varlen > namelen )
|
||||
continue;
|
||||
|
||||
match = ( wcsncmp( var, name, varlen) == 0 );
|
||||
|
||||
|
||||
if( !match )
|
||||
{
|
||||
match_no_case = ( wcsncasecmp( var, name, varlen) == 0 );
|
||||
|
@ -1659,11 +1659,11 @@ static int complete_variable( const wchar_t *whole_var,
|
|||
string_buffer_t comp;
|
||||
int flags = 0;
|
||||
int offset = 0;
|
||||
|
||||
|
||||
sb_init( &comp );
|
||||
if( match )
|
||||
{
|
||||
sb_append( &comp, &name[varlen] );
|
||||
sb_append( &comp, &name[varlen] );
|
||||
offset = varlen;
|
||||
}
|
||||
else
|
||||
|
@ -1672,23 +1672,23 @@ static int complete_variable( const wchar_t *whole_var,
|
|||
sb_append( &comp, name );
|
||||
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
|
||||
}
|
||||
|
||||
|
||||
value = expand_escape_variable( value_unescaped );
|
||||
|
||||
sb_init( &desc );
|
||||
sb_printf( &desc, COMPLETE_VAR_DESC_VAL, value );
|
||||
|
||||
completion_allocate( comp_list,
|
||||
|
||||
completion_allocate( comp_list,
|
||||
(wchar_t *)comp.buff,
|
||||
(wchar_t *)desc.buff,
|
||||
flags );
|
||||
res =1;
|
||||
|
||||
|
||||
free( value );
|
||||
sb_destroy( &desc );
|
||||
sb_destroy( &comp );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1698,7 +1698,7 @@ static int complete_variable( const wchar_t *whole_var,
|
|||
|
||||
/**
|
||||
Search the specified string for the \$ sign. If found, try to
|
||||
complete as an environment variable.
|
||||
complete as an environment variable.
|
||||
|
||||
\return 0 if unable to complete, 1 otherwise
|
||||
*/
|
||||
|
@ -1735,7 +1735,7 @@ static int try_complete_user( const wchar_t *cmd,
|
|||
const wchar_t *first_char=cmd;
|
||||
int res=0;
|
||||
double start_time = timef();
|
||||
|
||||
|
||||
if( *first_char ==L'~' && !wcschr(first_char, L'/'))
|
||||
{
|
||||
const wchar_t *user_name = first_char+1;
|
||||
|
@ -1744,19 +1744,19 @@ static int try_complete_user( const wchar_t *cmd,
|
|||
{
|
||||
struct passwd *pw;
|
||||
int name_len = wcslen( user_name );
|
||||
|
||||
|
||||
setpwent();
|
||||
|
||||
|
||||
while((pw=getpwent()) != 0)
|
||||
{
|
||||
double current_time = timef();
|
||||
wchar_t *pw_name;
|
||||
|
||||
if( current_time - start_time > 0.2 )
|
||||
if( current_time - start_time > 0.2 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
pw_name = str2wcs( pw->pw_name );
|
||||
|
||||
if( pw_name )
|
||||
|
@ -1764,26 +1764,26 @@ static int try_complete_user( const wchar_t *cmd,
|
|||
if( wcsncmp( user_name, pw_name, name_len )==0 )
|
||||
{
|
||||
string_buffer_t desc;
|
||||
|
||||
|
||||
sb_init( &desc );
|
||||
sb_printf( &desc,
|
||||
COMPLETE_USER_DESC,
|
||||
pw_name );
|
||||
|
||||
completion_allocate( comp,
|
||||
|
||||
completion_allocate( comp,
|
||||
&pw_name[name_len],
|
||||
(wchar_t *)desc.buff,
|
||||
COMPLETE_NO_SPACE );
|
||||
|
||||
|
||||
res=1;
|
||||
|
||||
|
||||
sb_destroy( &desc );
|
||||
}
|
||||
else if( wcsncasecmp( user_name, pw_name, name_len )==0 )
|
||||
{
|
||||
string_buffer_t name;
|
||||
string_buffer_t desc;
|
||||
|
||||
string_buffer_t name;
|
||||
string_buffer_t desc;
|
||||
|
||||
sb_init( &name );
|
||||
sb_init( &desc );
|
||||
sb_printf( &name,
|
||||
|
@ -1792,16 +1792,16 @@ static int try_complete_user( const wchar_t *cmd,
|
|||
sb_printf( &desc,
|
||||
COMPLETE_USER_DESC,
|
||||
pw_name );
|
||||
|
||||
completion_allocate( comp,
|
||||
|
||||
completion_allocate( comp,
|
||||
(wchar_t *)name.buff,
|
||||
(wchar_t *)desc.buff,
|
||||
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE );
|
||||
res=1;
|
||||
|
||||
|
||||
sb_destroy( &desc );
|
||||
sb_destroy( &name );
|
||||
|
||||
|
||||
}
|
||||
free( pw_name );
|
||||
}
|
||||
|
@ -1862,9 +1862,9 @@ void complete( const wchar_t *cmd,
|
|||
if( !done )
|
||||
{
|
||||
pos = cursor_pos-(cmdsubst_begin-cmd);
|
||||
|
||||
|
||||
buff = wcsndup( cmdsubst_begin, cmdsubst_end-cmdsubst_begin );
|
||||
|
||||
|
||||
if( !buff )
|
||||
done=1;
|
||||
}
|
||||
|
@ -1887,7 +1887,7 @@ void complete( const wchar_t *cmd,
|
|||
|
||||
wchar_t *ncmd = tok_last( &tok );
|
||||
int is_ddash = (wcscmp( ncmd, L"--" ) == 0) && ( (tok_get_pos( &tok )+2) < pos );
|
||||
|
||||
|
||||
if( !had_cmd )
|
||||
{
|
||||
|
||||
|
@ -1908,17 +1908,17 @@ void complete( const wchar_t *cmd,
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( !is_ddash ||
|
||||
( (use_command && use_function && use_builtin ) ) )
|
||||
{
|
||||
int token_end;
|
||||
|
||||
|
||||
free( current_command );
|
||||
current_command = wcsdup( ncmd );
|
||||
|
||||
|
||||
token_end = tok_get_pos( &tok ) + wcslen( ncmd );
|
||||
|
||||
|
||||
on_command = (pos <= token_end );
|
||||
had_cmd=1;
|
||||
}
|
||||
|
@ -1931,10 +1931,10 @@ void complete( const wchar_t *cmd,
|
|||
had_ddash = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOK_END:
|
||||
case TOK_PIPE:
|
||||
case TOK_BACKGROUND:
|
||||
|
@ -1946,20 +1946,20 @@ void complete( const wchar_t *cmd,
|
|||
use_builtin = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOK_ERROR:
|
||||
{
|
||||
end_loop=1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( tok_get_pos( &tok ) >= pos )
|
||||
{
|
||||
end_loop=1;
|
||||
}
|
||||
|
||||
|
||||
tok_next( &tok );
|
||||
|
||||
}
|
||||
|
@ -1974,7 +1974,7 @@ void complete( const wchar_t *cmd,
|
|||
current_token = wcsndup( tok_begin, cursor_pos-(tok_begin-cmd) );
|
||||
|
||||
prev_token = prev_begin ? wcsndup( prev_begin, prev_end - prev_begin ): wcsdup(L"");
|
||||
|
||||
|
||||
// debug( 0, L"on_command: %d, %ls %ls\n", on_command, current_command, current_token );
|
||||
|
||||
/*
|
||||
|
@ -1983,9 +1983,9 @@ void complete( const wchar_t *cmd,
|
|||
case, complete using the builtins completions, not using a
|
||||
subcommand.
|
||||
*/
|
||||
|
||||
|
||||
if( (on_command || (wcscmp( current_token, L"--" ) == 0 ) ) &&
|
||||
(current_token[0] == L'-') &&
|
||||
(current_token[0] == L'-') &&
|
||||
!(use_command && use_function && use_builtin ) )
|
||||
{
|
||||
free( current_command );
|
||||
|
@ -1993,11 +1993,11 @@ void complete( const wchar_t *cmd,
|
|||
current_command = wcsdup( L"builtin" );
|
||||
else
|
||||
current_command = wcsdup( L"command" );
|
||||
|
||||
|
||||
had_cmd = 1;
|
||||
on_command = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Use command completions if in between commands
|
||||
*/
|
||||
|
@ -2005,7 +2005,7 @@ void complete( const wchar_t *cmd,
|
|||
{
|
||||
on_command=1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
We don't want these to be null
|
||||
*/
|
||||
|
@ -2014,12 +2014,12 @@ void complete( const wchar_t *cmd,
|
|||
{
|
||||
current_token = wcsdup(L"");
|
||||
}
|
||||
|
||||
|
||||
if( !current_command )
|
||||
{
|
||||
current_command = wcsdup(L"");
|
||||
}
|
||||
|
||||
|
||||
if( !prev_token )
|
||||
{
|
||||
prev_token = wcsdup(L"");
|
||||
|
@ -2036,31 +2036,31 @@ void complete( const wchar_t *cmd,
|
|||
else
|
||||
{
|
||||
int do_file=0;
|
||||
|
||||
|
||||
wchar_t *current_command_unescape = unescape( current_command, 0 );
|
||||
wchar_t *prev_token_unescape = unescape( prev_token, 0 );
|
||||
wchar_t *current_token_unescape = unescape( current_token, UNESCAPE_INCOMPLETE );
|
||||
|
||||
|
||||
if( current_token_unescape && prev_token_unescape && current_token_unescape )
|
||||
{
|
||||
do_file = complete_param( current_command_unescape,
|
||||
prev_token_unescape,
|
||||
current_token_unescape,
|
||||
!had_ddash,
|
||||
do_file = complete_param( current_command_unescape,
|
||||
prev_token_unescape,
|
||||
current_token_unescape,
|
||||
!had_ddash,
|
||||
comp );
|
||||
}
|
||||
|
||||
|
||||
free( current_command_unescape );
|
||||
free( prev_token_unescape );
|
||||
free( current_token_unescape );
|
||||
|
||||
|
||||
/*
|
||||
If we have found no command specific completions at
|
||||
all, fall back to using file completions.
|
||||
*/
|
||||
if( !al_get_count( comp ) )
|
||||
do_file = 1;
|
||||
|
||||
|
||||
/*
|
||||
This function wants the unescaped string
|
||||
*/
|
||||
|
@ -2068,7 +2068,7 @@ void complete( const wchar_t *cmd,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( current_token );
|
||||
free( current_command );
|
||||
free( prev_token );
|
||||
|
|
64
complete.h
64
complete.h
|
@ -16,39 +16,39 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Use all completions
|
||||
/**
|
||||
Use all completions
|
||||
*/
|
||||
#define SHARED 0
|
||||
/**
|
||||
Do not use file completion
|
||||
/**
|
||||
Do not use file completion
|
||||
*/
|
||||
#define NO_FILES 1
|
||||
/**
|
||||
Require a parameter after completion
|
||||
/**
|
||||
Require a parameter after completion
|
||||
*/
|
||||
#define NO_COMMON 2
|
||||
/**
|
||||
/**
|
||||
Only use the argument list specifies with completion after
|
||||
option. This is the same as (NO_FILES & NO_COMMON)
|
||||
*/
|
||||
#define EXCLUSIVE 3
|
||||
|
||||
/**
|
||||
Command is a path
|
||||
/**
|
||||
Command is a path
|
||||
*/
|
||||
#define PATH 1
|
||||
/**
|
||||
Command is not a path
|
||||
/**
|
||||
Command is not a path
|
||||
*/
|
||||
#define COMMAND 0
|
||||
|
||||
/**
|
||||
/**
|
||||
Separator between completion and description
|
||||
*/
|
||||
#define COMPLETE_SEP L'\004'
|
||||
|
||||
/**
|
||||
/**
|
||||
Separator between completion and description
|
||||
*/
|
||||
#define COMPLETE_SEP_STR L"\004"
|
||||
|
@ -73,7 +73,7 @@
|
|||
#define COMPLETE_NO_SPACE 1
|
||||
|
||||
/**
|
||||
This compeltion is case insensitive.
|
||||
This compeltion is case insensitive.
|
||||
|
||||
Warning: The contents of the completion_t structure is actually
|
||||
different if this flag is set! Specifically, the completion string
|
||||
|
@ -115,7 +115,7 @@ typedef struct
|
|||
const wchar_t *description;
|
||||
|
||||
/**
|
||||
Flags determining the completion behaviour.
|
||||
Flags determining the completion behaviour.
|
||||
|
||||
Determines whether a space should be inserted after this
|
||||
compeltion if it is the only possible completion using the
|
||||
|
@ -132,17 +132,17 @@ typedef struct
|
|||
|
||||
/**
|
||||
|
||||
Add a completion.
|
||||
Add a completion.
|
||||
|
||||
All supplied values are copied, they should be freed by or otherwise
|
||||
disposed by the caller.
|
||||
|
||||
Examples:
|
||||
|
||||
Examples:
|
||||
|
||||
The command 'gcc -o' requires that a file follows it, so the
|
||||
NO_COMMON option is suitable. This can be done using the following
|
||||
line:
|
||||
|
||||
|
||||
complete -c gcc -s o -r
|
||||
|
||||
The command 'grep -d' required that one of the strings 'read',
|
||||
|
@ -159,7 +159,7 @@ typedef struct
|
|||
will be interpreted as the command name.
|
||||
\param short_opt The single character name of an option. (-a is a short option, --all and -funroll are long options)
|
||||
\param long_opt The multi character name of an option. (-a is a short option, --all and -funroll are long options)
|
||||
\param long_mode Whether to use old style, single dash long options.
|
||||
\param long_mode Whether to use old style, single dash long options.
|
||||
\param result_mode Whether to search further completions when this
|
||||
completion has been succesfully matched. If result_mode is SHARED,
|
||||
any other completions may also be used. If result_mode is NO_FILES,
|
||||
|
@ -172,16 +172,16 @@ typedef struct
|
|||
\param condition a command to be run to check it this completion should be used. If \c condition is empty, the completion is always used.
|
||||
\param flags A set of completion flags
|
||||
*/
|
||||
void complete_add( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
void complete_add( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
wchar_t short_opt,
|
||||
const wchar_t *long_opt,
|
||||
int long_mode,
|
||||
int result_mode,
|
||||
int long_mode,
|
||||
int result_mode,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc,
|
||||
int flags );
|
||||
int flags );
|
||||
/**
|
||||
Sets whether the completion list for this command is complete. If
|
||||
true, any options not matching one of the provided options will be
|
||||
|
@ -194,8 +194,8 @@ void complete_set_authoritative( const wchar_t *cmd,
|
|||
/**
|
||||
Remove a previously defined completion
|
||||
*/
|
||||
void complete_remove( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
void complete_remove( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
wchar_t short_opt,
|
||||
const wchar_t *long_opt );
|
||||
|
||||
|
@ -212,7 +212,7 @@ void complete_remove( const wchar_t *cmd,
|
|||
void complete( const wchar_t *cmd, array_list_t *out );
|
||||
|
||||
/**
|
||||
Print a list of all current completions into the string_buffer_t.
|
||||
Print a list of all current completions into the string_buffer_t.
|
||||
|
||||
\param out The string_buffer_t to write completions to
|
||||
*/
|
||||
|
@ -221,16 +221,16 @@ void complete_print( string_buffer_t *out );
|
|||
/**
|
||||
Tests if the specified option is defined for the specified command
|
||||
*/
|
||||
int complete_is_valid_option( const wchar_t *str,
|
||||
const wchar_t *opt,
|
||||
int complete_is_valid_option( const wchar_t *str,
|
||||
const wchar_t *opt,
|
||||
array_list_t *errors );
|
||||
|
||||
/**
|
||||
Tests if the specified argument is valid for the specified option
|
||||
and command
|
||||
*/
|
||||
int complete_is_valid_argument( const wchar_t *str,
|
||||
const wchar_t *opt,
|
||||
int complete_is_valid_argument( const wchar_t *str,
|
||||
const wchar_t *opt,
|
||||
const wchar_t *arg );
|
||||
|
||||
|
||||
|
|
26
env.h
26
env.h
|
@ -6,8 +6,10 @@
|
|||
#define FISH_ENV_H
|
||||
|
||||
#include <wchar.h>
|
||||
#include <map>
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
Flag for local (to the current block) variable
|
||||
|
@ -63,7 +65,7 @@ void env_destroy();
|
|||
|
||||
|
||||
/**
|
||||
Set the value of the environment variable whose name matches key to val.
|
||||
Set the value of the environment variable whose name matches key to val.
|
||||
|
||||
Memory policy: All keys and values are copied, the parameters can and should be freed by the caller afterwards
|
||||
|
||||
|
@ -79,7 +81,7 @@ void env_destroy();
|
|||
* ENV_INVALID, the variable name or mode was invalid
|
||||
*/
|
||||
|
||||
int env_set( const wchar_t *key,
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int mode );
|
||||
|
||||
|
@ -93,6 +95,11 @@ int env_set( const wchar_t *key,
|
|||
*/
|
||||
wchar_t *env_get( const wchar_t *key );
|
||||
|
||||
/**
|
||||
Gets the variable with the specified name, or an empty string if it does not exist.
|
||||
*/
|
||||
wcstring env_get_string( const wchar_t *key );
|
||||
|
||||
/**
|
||||
Returns 1 if the specified key exists. This can't be reliably done
|
||||
using env_get, since env_get returns null for 0-element arrays
|
||||
|
@ -104,7 +111,7 @@ int env_exist( const wchar_t *key, int mode );
|
|||
|
||||
/**
|
||||
Remove environemnt variable
|
||||
|
||||
|
||||
\param key The name of the variable to remove
|
||||
\param mode should be ENV_USER if this is a remove request from the user, 0 otherwise. If this is a user request, read-only variables can not be removed. The mode may also specify the scope of the variable that should be erased.
|
||||
|
||||
|
@ -138,5 +145,18 @@ void env_get_names( array_list_t *l, int flags );
|
|||
*/
|
||||
int env_set_pwd();
|
||||
|
||||
class env_vars {
|
||||
std::map<wcstring, wcstring> vars;
|
||||
|
||||
public:
|
||||
env_vars(const wchar_t * const * keys);
|
||||
env_vars(void);
|
||||
|
||||
const wchar_t *get(const wchar_t *key) const;
|
||||
|
||||
// vars necessary for highlighting
|
||||
static const wchar_t * const highlighting_keys[];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -83,27 +83,27 @@ static int get_socket( int fork_ok )
|
|||
{
|
||||
int s, len;
|
||||
struct sockaddr_un local;
|
||||
|
||||
|
||||
char *name;
|
||||
wchar_t *wdir;
|
||||
wchar_t *wuname;
|
||||
wchar_t *wuname;
|
||||
char *dir =0, *uname=0;
|
||||
|
||||
get_socket_count++;
|
||||
wdir = path;
|
||||
wuname = user;
|
||||
|
||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
|
||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
wperror(L"socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( wdir )
|
||||
dir = wcs2str(wdir );
|
||||
else
|
||||
dir = strdup("/tmp");
|
||||
|
||||
|
||||
if( wuname )
|
||||
uname = wcs2str(wuname );
|
||||
else
|
||||
|
@ -112,53 +112,53 @@ static int get_socket( int fork_ok )
|
|||
pw = getpwuid( getuid() );
|
||||
uname = strdup( pw->pw_name );
|
||||
}
|
||||
|
||||
name = malloc( strlen(dir) +
|
||||
strlen(uname) +
|
||||
strlen(SOCK_FILENAME) +
|
||||
|
||||
name = (char *)malloc( strlen(dir) +
|
||||
strlen(uname) +
|
||||
strlen(SOCK_FILENAME) +
|
||||
2 );
|
||||
|
||||
|
||||
strcpy( name, dir );
|
||||
strcat( name, "/" );
|
||||
strcat( name, SOCK_FILENAME );
|
||||
strcat( name, uname );
|
||||
|
||||
|
||||
free( dir );
|
||||
free( uname );
|
||||
|
||||
|
||||
debug( 3, L"Connect to socket %s at fd %2", name, s );
|
||||
|
||||
|
||||
local.sun_family = AF_UNIX;
|
||||
strcpy(local.sun_path, name );
|
||||
free( name );
|
||||
len = sizeof(local);
|
||||
|
||||
if( connect( s, (struct sockaddr *)&local, len) == -1 )
|
||||
|
||||
if( connect( s, (struct sockaddr *)&local, len) == -1 )
|
||||
{
|
||||
close( s );
|
||||
if( fork_ok && start_fishd )
|
||||
{
|
||||
debug( 2, L"Could not connect to socket %d, starting fishd", s );
|
||||
|
||||
|
||||
start_fishd();
|
||||
|
||||
|
||||
return get_socket( 0 );
|
||||
}
|
||||
|
||||
|
||||
debug( 1, L"Could not connect to universal variable server, already tried manual restart (or no command supplied). You will not be able to share variable values between fish sessions. Is fish properly installed?" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( (fcntl( s, F_SETFL, O_NONBLOCK ) != 0) || (fcntl( s, F_SETFD, FD_CLOEXEC ) != 0) )
|
||||
|
||||
if( (fcntl( s, F_SETFL, O_NONBLOCK ) != 0) || (fcntl( s, F_SETFD, FD_CLOEXEC ) != 0) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
close( s );
|
||||
|
||||
close( s );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug( 3, L"Connected to fd %d", s );
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ static int get_socket( int fork_ok )
|
|||
Callback function used whenever a new fishd message is recieved
|
||||
*/
|
||||
static void callback( int type, const wchar_t *name, const wchar_t *val )
|
||||
{
|
||||
{
|
||||
if( type == BARRIER_REPLY )
|
||||
{
|
||||
barrier_reply = 1;
|
||||
|
@ -174,8 +174,8 @@ static void callback( int type, const wchar_t *name, const wchar_t *val )
|
|||
else
|
||||
{
|
||||
if( external_callback )
|
||||
external_callback( type, name, val );
|
||||
}
|
||||
external_callback( type, name, val );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,21 +186,21 @@ static void check_connection()
|
|||
{
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
|
||||
if( env_universal_server.killme )
|
||||
{
|
||||
debug( 3, L"Lost connection to universal variable server." );
|
||||
|
||||
|
||||
if( close( env_universal_server.fd ) )
|
||||
{
|
||||
wperror( L"close" );
|
||||
}
|
||||
|
||||
|
||||
env_universal_server.fd = -1;
|
||||
env_universal_server.killme=0;
|
||||
env_universal_server.input.used=0;
|
||||
env_universal_server.input.used=0;
|
||||
env_universal_read_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,10 +210,10 @@ static void env_universal_remove_all()
|
|||
{
|
||||
array_list_t lst;
|
||||
int i;
|
||||
|
||||
|
||||
al_init( &lst );
|
||||
|
||||
env_universal_common_get_names( &lst,
|
||||
|
||||
env_universal_common_get_names( &lst,
|
||||
1,
|
||||
1 );
|
||||
|
||||
|
@ -224,7 +224,7 @@ static void env_universal_remove_all()
|
|||
}
|
||||
|
||||
al_destroy( &lst );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,9 +237,9 @@ static void reconnect()
|
|||
{
|
||||
if( get_socket_count >= RECONNECT_COUNT )
|
||||
return;
|
||||
|
||||
|
||||
debug( 3, L"Get new fishd connection" );
|
||||
|
||||
|
||||
init = 0;
|
||||
env_universal_server.buffer_consumed = env_universal_server.buffer_used = 0;
|
||||
env_universal_server.fd = get_socket(1);
|
||||
|
@ -252,22 +252,22 @@ static void reconnect()
|
|||
}
|
||||
|
||||
|
||||
void env_universal_init( wchar_t * p,
|
||||
wchar_t *u,
|
||||
void env_universal_init( wchar_t * p,
|
||||
wchar_t *u,
|
||||
void (*sf)(),
|
||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
|
||||
{
|
||||
path=p;
|
||||
user=u;
|
||||
start_fishd=sf;
|
||||
start_fishd=sf;
|
||||
external_callback = cb;
|
||||
|
||||
connection_init( &env_universal_server, -1 );
|
||||
|
||||
|
||||
env_universal_server.fd = get_socket(1);
|
||||
env_universal_common_init( &callback );
|
||||
env_universal_read_all();
|
||||
init = 1;
|
||||
env_universal_read_all();
|
||||
init = 1;
|
||||
if( env_universal_server.fd >= 0 )
|
||||
{
|
||||
env_universal_barrier();
|
||||
|
@ -285,7 +285,7 @@ void env_universal_destroy()
|
|||
{
|
||||
wperror( L"fcntl" );
|
||||
}
|
||||
try_send_all( &env_universal_server );
|
||||
try_send_all( &env_universal_server );
|
||||
}
|
||||
|
||||
connection_destroy( &env_universal_server );
|
||||
|
@ -305,22 +305,22 @@ int env_universal_read_all()
|
|||
|
||||
if( env_universal_server.fd == -1 )
|
||||
{
|
||||
reconnect();
|
||||
reconnect();
|
||||
if( env_universal_server.fd == -1 )
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( env_universal_server.fd != -1 )
|
||||
{
|
||||
read_message( &env_universal_server );
|
||||
check_connection();
|
||||
check_connection();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 2, L"No connection to universal variable server" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *env_universal_get( const wchar_t *name )
|
||||
|
@ -329,7 +329,7 @@ wchar_t *env_universal_get( const wchar_t *name )
|
|||
return 0;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
|
||||
return env_universal_common_get( name );
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ int env_universal_get_export( const wchar_t *name )
|
|||
return 0;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
|
||||
return env_universal_common_get_export( name );
|
||||
}
|
||||
|
||||
|
@ -366,19 +366,19 @@ void env_universal_barrier()
|
|||
debug( 3, L"Create barrier" );
|
||||
while( 1 )
|
||||
{
|
||||
try_send_all( &env_universal_server );
|
||||
check_connection();
|
||||
|
||||
try_send_all( &env_universal_server );
|
||||
check_connection();
|
||||
|
||||
if( q_empty( &env_universal_server.unsent ) )
|
||||
break;
|
||||
|
||||
|
||||
if( env_universal_server.fd == -1 )
|
||||
{
|
||||
reconnect();
|
||||
debug( 2, L"barrier interrupted, exiting" );
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( env_universal_server.fd, &fds );
|
||||
select( env_universal_server.fd+1, 0, &fds, 0, 0 );
|
||||
|
@ -394,10 +394,10 @@ void env_universal_barrier()
|
|||
{
|
||||
reconnect();
|
||||
debug( 2, L"barrier interrupted, exiting (2)" );
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( env_universal_server.fd, &fds );
|
||||
FD_SET( env_universal_server.fd, &fds );
|
||||
select( env_universal_server.fd+1, &fds, 0, 0, 0 );
|
||||
env_universal_read_all();
|
||||
}
|
||||
|
@ -405,25 +405,25 @@ void env_universal_barrier()
|
|||
}
|
||||
|
||||
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *value, int exportv )
|
||||
{
|
||||
message_t *msg;
|
||||
|
||||
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
|
||||
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
||||
|
||||
if( is_dead() )
|
||||
{
|
||||
env_universal_common_set( name, value, export );
|
||||
env_universal_common_set( name, value, exportv );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = create_message( export?SET_EXPORT:SET,
|
||||
name,
|
||||
msg = create_message( exportv?SET_EXPORT:SET,
|
||||
name,
|
||||
value);
|
||||
|
||||
if( !msg )
|
||||
|
@ -431,7 +431,7 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
|||
debug( 1, L"Could not create universal variable message" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
|
@ -441,18 +441,18 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
|||
int env_universal_remove( const wchar_t *name )
|
||||
{
|
||||
int res;
|
||||
|
||||
|
||||
message_t *msg;
|
||||
if( !init )
|
||||
return 1;
|
||||
|
||||
|
||||
CHECK( name, 1 );
|
||||
|
||||
res = !env_universal_common_get( name );
|
||||
debug( 3,
|
||||
L"env_universal_remove( \"%ls\" )",
|
||||
name );
|
||||
|
||||
|
||||
if( is_dead() )
|
||||
{
|
||||
env_universal_common_remove( name );
|
||||
|
@ -464,7 +464,7 @@ int env_universal_remove( const wchar_t *name )
|
|||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -476,8 +476,8 @@ void env_universal_get_names( array_list_t *l,
|
|||
return;
|
||||
|
||||
CHECK( l, );
|
||||
|
||||
env_universal_common_get_names( l,
|
||||
|
||||
env_universal_common_get_names( l,
|
||||
show_exported,
|
||||
show_unexported );
|
||||
show_unexported );
|
||||
}
|
||||
|
|
|
@ -17,7 +17,10 @@ extern connection_t env_universal_server;
|
|||
/**
|
||||
Initialize the envuni library
|
||||
*/
|
||||
void env_universal_init();
|
||||
void env_universal_init( wchar_t * p,
|
||||
wchar_t *u,
|
||||
void (*sf)(),
|
||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ));
|
||||
/**
|
||||
Free memory used by envuni
|
||||
*/
|
||||
|
@ -37,10 +40,10 @@ int env_universal_get_export( const wchar_t *name );
|
|||
/**
|
||||
Set the value of a universal variable
|
||||
*/
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *val, int export );
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *val, int exportv );
|
||||
/**
|
||||
Erase a universal variable
|
||||
|
||||
|
||||
\return zero if the variable existed, and non-zero if the variable did not exist
|
||||
*/
|
||||
int env_universal_remove( const wchar_t *name );
|
||||
|
@ -52,7 +55,7 @@ int env_universal_read_all();
|
|||
|
||||
/**
|
||||
Get the names of all universal variables
|
||||
|
||||
|
||||
\param l the list to insert the names into
|
||||
\param show_exported whether exported variables should be shown
|
||||
\param show_unexported whether unexported variables should be shown
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
*/
|
||||
typedef struct var_uni_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
int exportv; /**< Whether the variable should be exported */
|
||||
wchar_t val[1]; /**< The value of the variable */
|
||||
}
|
||||
var_uni_entry_t;
|
||||
|
@ -109,8 +109,8 @@ hash_table_t env_universal_var;
|
|||
/**
|
||||
Callback function, should be called on all events
|
||||
*/
|
||||
void (*callback)( int type,
|
||||
const wchar_t *key,
|
||||
void (*callback)( int type,
|
||||
const wchar_t *key,
|
||||
const wchar_t *val );
|
||||
|
||||
/**
|
||||
|
@ -140,8 +140,8 @@ static char *iconv_utf8_names[]=
|
|||
*/
|
||||
static char *iconv_wide_names_unknown[]=
|
||||
{
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
0
|
||||
}
|
||||
;
|
||||
|
@ -151,12 +151,12 @@ static char *iconv_wide_names_unknown[]=
|
|||
*/
|
||||
static char *iconv_wide_names_4[]=
|
||||
{
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
"ucs-4", "UCS-4",
|
||||
"ucs4", "UCS4",
|
||||
"utf-32", "UTF-32",
|
||||
"utf32", "UTF32",
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
"ucs-4", "UCS-4",
|
||||
"ucs4", "UCS4",
|
||||
"utf-32", "UTF-32",
|
||||
"utf32", "UTF32",
|
||||
0
|
||||
}
|
||||
;
|
||||
|
@ -166,12 +166,12 @@ static char *iconv_wide_names_4[]=
|
|||
*/
|
||||
static char *iconv_wide_names_2[]=
|
||||
{
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
"ucs-2", "UCS-2",
|
||||
"ucs2", "UCS2",
|
||||
"utf-16", "UTF-16",
|
||||
"utf16", "UTF16",
|
||||
"wchar_t", "WCHAR_T",
|
||||
"wchar", "WCHAR",
|
||||
"ucs-2", "UCS-2",
|
||||
"ucs2", "UCS2",
|
||||
"utf-16", "UTF-16",
|
||||
"utf16", "UTF16",
|
||||
0
|
||||
}
|
||||
;
|
||||
|
@ -196,7 +196,7 @@ static wchar_t *utf2wcs( const char *in )
|
|||
|
||||
switch (sizeof (wchar_t))
|
||||
{
|
||||
|
||||
|
||||
case 2:
|
||||
to_name = iconv_wide_names_2;
|
||||
break;
|
||||
|
@ -204,15 +204,15 @@ static wchar_t *utf2wcs( const char *in )
|
|||
case 4:
|
||||
to_name = iconv_wide_names_4;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
to_name = iconv_wide_names_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
The line protocol fish uses is always utf-8.
|
||||
The line protocol fish uses is always utf-8.
|
||||
*/
|
||||
char **from_name = iconv_utf8_names;
|
||||
|
||||
|
@ -220,13 +220,13 @@ static wchar_t *utf2wcs( const char *in )
|
|||
size_t out_len = sizeof( wchar_t )*(in_len+2);
|
||||
size_t nconv;
|
||||
char *nout;
|
||||
|
||||
out = malloc( out_len );
|
||||
|
||||
out = (wchar_t *)malloc( out_len );
|
||||
nout = (char *)out;
|
||||
|
||||
if( !out )
|
||||
return 0;
|
||||
|
||||
|
||||
for( i=0; to_name[i]; i++ )
|
||||
{
|
||||
for( j=0; from_name[j]; j++ )
|
||||
|
@ -236,7 +236,7 @@ static wchar_t *utf2wcs( const char *in )
|
|||
if( cd != (iconv_t) -1)
|
||||
{
|
||||
goto start_conversion;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,23 +246,23 @@ static wchar_t *utf2wcs( const char *in )
|
|||
if (cd == (iconv_t) -1)
|
||||
{
|
||||
/* Something went wrong. */
|
||||
debug( 0, L"Could not perform utf-8 conversion" );
|
||||
debug( 0, L"Could not perform utf-8 conversion" );
|
||||
if(errno != EINVAL)
|
||||
wperror( L"iconv_open" );
|
||||
|
||||
|
||||
/* Terminate the output string. */
|
||||
free(out);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
nconv = iconv( cd, (char **)&in, &in_len, &nout, &out_len );
|
||||
|
||||
|
||||
if (nconv == (size_t) -1)
|
||||
{
|
||||
debug( 0, L"Error while converting from utf string" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
*((wchar_t *) nout) = L'\0';
|
||||
|
||||
/*
|
||||
|
@ -281,12 +281,12 @@ static wchar_t *utf2wcs( const char *in )
|
|||
}
|
||||
free( out_old );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (iconv_close (cd) != 0)
|
||||
wperror (L"iconv_close");
|
||||
|
||||
return out;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,7 +296,7 @@ static char *wcs2utf( const wchar_t *in )
|
|||
{
|
||||
iconv_t cd=(iconv_t) -1;
|
||||
int i,j;
|
||||
|
||||
|
||||
char *char_in = (char *)in;
|
||||
char *out;
|
||||
|
||||
|
@ -310,7 +310,7 @@ static char *wcs2utf( const wchar_t *in )
|
|||
|
||||
switch (sizeof (wchar_t))
|
||||
{
|
||||
|
||||
|
||||
case 2:
|
||||
from_name = iconv_wide_names_2;
|
||||
break;
|
||||
|
@ -318,7 +318,7 @@ static char *wcs2utf( const wchar_t *in )
|
|||
case 4:
|
||||
from_name = iconv_wide_names_4;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
from_name = iconv_wide_names_unknown;
|
||||
break;
|
||||
|
@ -330,24 +330,24 @@ static char *wcs2utf( const wchar_t *in )
|
|||
size_t out_len = sizeof( char )*( (MAX_UTF8_BYTES*in_len)+1);
|
||||
size_t nconv;
|
||||
char *nout;
|
||||
|
||||
out = malloc( out_len );
|
||||
|
||||
out = (char *)malloc( out_len );
|
||||
nout = (char *)out;
|
||||
in_len *= sizeof( wchar_t );
|
||||
|
||||
if( !out )
|
||||
return 0;
|
||||
|
||||
|
||||
for( i=0; to_name[i]; i++ )
|
||||
{
|
||||
for( j=0; from_name[j]; j++ )
|
||||
{
|
||||
cd = iconv_open ( to_name[i], from_name[j] );
|
||||
|
||||
|
||||
if( cd != (iconv_t) -1)
|
||||
{
|
||||
goto start_conversion;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -357,17 +357,17 @@ static char *wcs2utf( const wchar_t *in )
|
|||
if (cd == (iconv_t) -1)
|
||||
{
|
||||
/* Something went wrong. */
|
||||
debug( 0, L"Could not perform utf-8 conversion" );
|
||||
debug( 0, L"Could not perform utf-8 conversion" );
|
||||
if(errno != EINVAL)
|
||||
wperror( L"iconv_open" );
|
||||
|
||||
|
||||
/* Terminate the output string. */
|
||||
free(out);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
nconv = iconv( cd, &char_in, &in_len, &nout, &out_len );
|
||||
|
||||
|
||||
|
||||
if (nconv == (size_t) -1)
|
||||
{
|
||||
|
@ -375,13 +375,13 @@ static char *wcs2utf( const wchar_t *in )
|
|||
debug( 0, L"Error while converting from to string" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
*nout = '\0';
|
||||
|
||||
|
||||
if (iconv_close (cd) != 0)
|
||||
wperror (L"iconv_close");
|
||||
|
||||
return out;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,9 +421,9 @@ static int read_byte( connection_t *src )
|
|||
int res;
|
||||
|
||||
res = read( src->fd, src->buffer, ENV_UNIVERSAL_BUFFER_SIZE );
|
||||
|
||||
|
||||
// debug(4, L"Read chunk '%.*s'", res, src->buffer );
|
||||
|
||||
|
||||
if( res < 0 )
|
||||
{
|
||||
|
||||
|
@ -432,20 +432,20 @@ static int read_byte( connection_t *src )
|
|||
{
|
||||
return ENV_UNIVERSAL_AGAIN;
|
||||
}
|
||||
|
||||
|
||||
return ENV_UNIVERSAL_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( res == 0 )
|
||||
{
|
||||
return ENV_UNIVERSAL_EOF;
|
||||
}
|
||||
|
||||
|
||||
src->buffer_consumed = 0;
|
||||
src->buffer_used = res;
|
||||
}
|
||||
|
||||
|
||||
return src->buffer[src->buffer_consumed++];
|
||||
|
||||
}
|
||||
|
@ -455,10 +455,10 @@ void read_message( connection_t *src )
|
|||
{
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
|
||||
int ib = read_byte( src );
|
||||
char b;
|
||||
|
||||
|
||||
switch( ib )
|
||||
{
|
||||
case ENV_UNIVERSAL_AGAIN:
|
||||
|
@ -483,43 +483,43 @@ void read_message( connection_t *src )
|
|||
{
|
||||
char c = 0;
|
||||
b_append( &src->input, &c, 1 );
|
||||
debug( 1,
|
||||
L"Universal variable connection closed while reading command. Partial command recieved: '%s'",
|
||||
debug( 1,
|
||||
L"Universal variable connection closed while reading command. Partial command recieved: '%s'",
|
||||
(wchar_t *)src->input.buff );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
b = (char)ib;
|
||||
|
||||
|
||||
if( b == '\n' )
|
||||
{
|
||||
wchar_t *msg;
|
||||
|
||||
|
||||
b = 0;
|
||||
b_append( &src->input, &b, 1 );
|
||||
|
||||
|
||||
msg = utf2wcs( src->input.buff );
|
||||
|
||||
|
||||
/*
|
||||
Before calling parse_message, we must empty reset
|
||||
everything, since the callback function could
|
||||
potentially call read_message.
|
||||
*/
|
||||
src->input.used=0;
|
||||
|
||||
|
||||
if( msg )
|
||||
{
|
||||
parse_message( msg, src );
|
||||
parse_message( msg, src );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0, _(L"Could not convert message '%s' to wide character string"), src->input.buff );
|
||||
}
|
||||
|
||||
|
||||
free( msg );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -534,7 +534,7 @@ void read_message( connection_t *src )
|
|||
void env_universal_common_remove( const wchar_t *name )
|
||||
{
|
||||
void *k, *v;
|
||||
hash_remove( &env_universal_var,
|
||||
hash_remove( &env_universal_var,
|
||||
name,
|
||||
&k,
|
||||
&v );
|
||||
|
@ -553,34 +553,34 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
|
|||
|
||||
if( msg[len] && msg[len]!= L' ' && msg[len] != L'\t' )
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export )
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int exportv )
|
||||
{
|
||||
var_uni_entry_t *entry;
|
||||
wchar_t *name;
|
||||
|
||||
CHECK( key, );
|
||||
CHECK( val, );
|
||||
|
||||
entry = malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
|
||||
entry = (var_uni_entry_t *)malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
name = wcsdup(key);
|
||||
|
||||
|
||||
if( !entry || !name )
|
||||
DIE_MEM();
|
||||
|
||||
entry->export=export;
|
||||
|
||||
|
||||
entry->exportv=exportv;
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
env_universal_common_remove( name );
|
||||
|
||||
|
||||
hash_put( &env_universal_var, name, entry );
|
||||
|
||||
|
||||
if( callback )
|
||||
{
|
||||
callback( export?SET_EXPORT:SET, name, val );
|
||||
callback( exportv?SET_EXPORT:SET, name, val );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,67 +588,67 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor
|
|||
/**
|
||||
Parse message msg
|
||||
*/
|
||||
static void parse_message( wchar_t *msg,
|
||||
static void parse_message( wchar_t *msg,
|
||||
connection_t *src )
|
||||
{
|
||||
// debug( 3, L"parse_message( %ls );", msg );
|
||||
|
||||
|
||||
if( msg[0] == L'#' )
|
||||
return;
|
||||
|
||||
|
||||
if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
|
||||
{
|
||||
wchar_t *name, *tmp;
|
||||
int export = match( msg, SET_EXPORT_STR );
|
||||
|
||||
name = msg+(export?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
||||
int exportv = match( msg, SET_EXPORT_STR );
|
||||
|
||||
name = msg+(exportv?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
||||
while( wcschr( L"\t ", *name ) )
|
||||
name++;
|
||||
|
||||
|
||||
tmp = wcschr( name, L':' );
|
||||
if( tmp )
|
||||
{
|
||||
wchar_t *key;
|
||||
wchar_t *val;
|
||||
|
||||
key = malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||
|
||||
key = (wchar_t *)malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||
memcpy( key, name, sizeof( wchar_t)*(tmp-name));
|
||||
key[tmp-name]=0;
|
||||
|
||||
|
||||
val = tmp+1;
|
||||
val = unescape( val, 0 );
|
||||
|
||||
env_universal_common_set( key, val, export );
|
||||
|
||||
|
||||
env_universal_common_set( key, val, exportv );
|
||||
|
||||
free( val );
|
||||
free( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 1, PARSE_ERR, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( match( msg, ERASE_STR ) )
|
||||
{
|
||||
wchar_t *name, *tmp;
|
||||
|
||||
|
||||
name = msg+wcslen(ERASE_STR);
|
||||
while( wcschr( L"\t ", *name ) )
|
||||
name++;
|
||||
|
||||
|
||||
tmp = name;
|
||||
while( iswalnum( *tmp ) || *tmp == L'_')
|
||||
tmp++;
|
||||
|
||||
|
||||
*tmp = 0;
|
||||
|
||||
|
||||
if( !wcslen( name ) )
|
||||
{
|
||||
debug( 1, PARSE_ERR, msg );
|
||||
}
|
||||
|
||||
env_universal_common_remove( name );
|
||||
|
||||
|
||||
if( callback )
|
||||
{
|
||||
callback( ERASE, name, 0 );
|
||||
|
@ -671,7 +671,7 @@ static void parse_message( wchar_t *msg,
|
|||
else
|
||||
{
|
||||
debug( 1, PARSE_ERR, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -684,7 +684,7 @@ static int try_send( message_t *msg,
|
|||
{
|
||||
|
||||
debug( 3,
|
||||
L"before write of %d chars to fd %d", strlen(msg->body), fd );
|
||||
L"before write of %d chars to fd %d", strlen(msg->body), fd );
|
||||
|
||||
int res = write( fd, msg->body, strlen(msg->body) );
|
||||
|
||||
|
@ -696,26 +696,26 @@ static int try_send( message_t *msg,
|
|||
{
|
||||
debug( 4, L"Failed to write message '%s'", msg->body );
|
||||
}
|
||||
|
||||
|
||||
if( res == -1 )
|
||||
{
|
||||
switch( errno )
|
||||
{
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
|
||||
default:
|
||||
debug( 2,
|
||||
L"Error while sending universal variable message to fd %d. Closing connection",
|
||||
fd );
|
||||
if( debug_level > 2 )
|
||||
wperror( L"write" );
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg->count--;
|
||||
|
||||
|
||||
if( !msg->count )
|
||||
{
|
||||
free( msg );
|
||||
|
@ -726,7 +726,7 @@ static int try_send( message_t *msg,
|
|||
void try_send_all( connection_t *c )
|
||||
{
|
||||
/* debug( 3,
|
||||
L"Send all updates to connection on fd %d",
|
||||
L"Send all updates to connection on fd %d",
|
||||
c->fd );*/
|
||||
while( !q_empty( &c->unsent) )
|
||||
{
|
||||
|
@ -735,12 +735,12 @@ void try_send_all( connection_t *c )
|
|||
case 1:
|
||||
q_get( &c->unsent);
|
||||
break;
|
||||
|
||||
|
||||
case 0:
|
||||
debug( 4,
|
||||
L"Socket full, send rest later" );
|
||||
L"Socket full, send rest later" );
|
||||
return;
|
||||
|
||||
|
||||
case -1:
|
||||
c->killme = 1;
|
||||
return;
|
||||
|
@ -779,16 +779,16 @@ static wchar_t *full_escape( const wchar_t *in )
|
|||
|
||||
|
||||
message_t *create_message( int type,
|
||||
const wchar_t *key_in,
|
||||
const wchar_t *key_in,
|
||||
const wchar_t *val_in )
|
||||
{
|
||||
message_t *msg=0;
|
||||
|
||||
|
||||
char *key=0;
|
||||
size_t sz;
|
||||
|
||||
// debug( 4, L"Crete message of type %d", type );
|
||||
|
||||
|
||||
if( key_in )
|
||||
{
|
||||
if( wcsvarname( key_in ) )
|
||||
|
@ -796,7 +796,7 @@ message_t *create_message( int type,
|
|||
debug( 0, L"Illegal variable name: '%ls'", key_in );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
key = wcs2utf(key_in);
|
||||
if( !key )
|
||||
{
|
||||
|
@ -806,8 +806,8 @@ message_t *create_message( int type,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case SET:
|
||||
|
@ -817,40 +817,40 @@ message_t *create_message( int type,
|
|||
{
|
||||
val_in=L"";
|
||||
}
|
||||
|
||||
|
||||
wchar_t *esc = full_escape( val_in );
|
||||
if( !esc )
|
||||
break;
|
||||
|
||||
|
||||
char *val = wcs2utf(esc );
|
||||
free(esc);
|
||||
|
||||
|
||||
sz = strlen(type==SET?SET_MBS:SET_EXPORT_MBS) + strlen(key) + strlen(val) + 4;
|
||||
msg = malloc( sizeof( message_t ) + sz );
|
||||
|
||||
msg = (message_t *)malloc( sizeof( message_t ) + sz );
|
||||
|
||||
if( !msg )
|
||||
DIE_MEM();
|
||||
|
||||
|
||||
strcpy( msg->body, (type==SET?SET_MBS:SET_EXPORT_MBS) );
|
||||
strcat( msg->body, " " );
|
||||
strcat( msg->body, key );
|
||||
strcat( msg->body, ":" );
|
||||
strcat( msg->body, val );
|
||||
strcat( msg->body, "\n" );
|
||||
|
||||
|
||||
free( val );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ERASE:
|
||||
{
|
||||
sz = strlen(ERASE_MBS) + strlen(key) + 3;
|
||||
msg = malloc( sizeof( message_t ) + sz );
|
||||
msg = (message_t *)malloc( sizeof( message_t ) + sz );
|
||||
|
||||
if( !msg )
|
||||
DIE_MEM();
|
||||
|
||||
|
||||
strcpy( msg->body, ERASE_MBS " " );
|
||||
strcat( msg->body, key );
|
||||
strcat( msg->body, "\n" );
|
||||
|
@ -859,24 +859,24 @@ message_t *create_message( int type,
|
|||
|
||||
case BARRIER:
|
||||
{
|
||||
msg = malloc( sizeof( message_t ) +
|
||||
msg = (message_t *)malloc( sizeof( message_t ) +
|
||||
strlen( BARRIER_MBS ) +2);
|
||||
if( !msg )
|
||||
DIE_MEM();
|
||||
strcpy( msg->body, BARRIER_MBS "\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case BARRIER_REPLY:
|
||||
{
|
||||
msg = malloc( sizeof( message_t ) +
|
||||
msg = (message_t *)malloc( sizeof( message_t ) +
|
||||
strlen( BARRIER_REPLY_MBS ) +2);
|
||||
if( !msg )
|
||||
DIE_MEM();
|
||||
strcpy( msg->body, BARRIER_REPLY_MBS "\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
debug( 0, L"create_message: Unknown message type" );
|
||||
|
@ -890,20 +890,20 @@ message_t *create_message( int type,
|
|||
|
||||
// debug( 4, L"Message body is '%s'", msg->body );
|
||||
|
||||
return msg;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
Function used with hash_foreach to insert keys of one table into
|
||||
another
|
||||
*/
|
||||
static void add_key_to_hash( void *key,
|
||||
static void add_key_to_hash( void *key,
|
||||
void *data,
|
||||
void *aux )
|
||||
{
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)data;
|
||||
if( ( e->export && get_names_show_exported) ||
|
||||
( !e->export && get_names_show_unexported) )
|
||||
if( ( e->exportv && get_names_show_exported) ||
|
||||
( !e->exportv && get_names_show_unexported) )
|
||||
al_push( (array_list_t *)aux, key );
|
||||
}
|
||||
|
||||
|
@ -913,25 +913,25 @@ void env_universal_common_get_names( array_list_t *l,
|
|||
{
|
||||
get_names_show_exported = show_exported;
|
||||
get_names_show_unexported = show_unexported;
|
||||
|
||||
hash_foreach2( &env_universal_var,
|
||||
|
||||
hash_foreach2( &env_universal_var,
|
||||
add_key_to_hash,
|
||||
l );
|
||||
}
|
||||
|
||||
wchar_t *env_universal_common_get( const wchar_t *name )
|
||||
{
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name );
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name );
|
||||
if( e )
|
||||
return e->val;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_universal_common_get_export( const wchar_t *name )
|
||||
{
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name );
|
||||
if( e )
|
||||
return e->export;
|
||||
return e->exportv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -952,17 +952,17 @@ static void enqueue( void *k,
|
|||
const wchar_t *key = (const wchar_t *)k;
|
||||
const var_uni_entry_t *val = (const var_uni_entry_t *)v;
|
||||
dyn_queue_t *queue = (dyn_queue_t *)q;
|
||||
|
||||
message_t *msg = create_message( val->export?SET_EXPORT:SET, key, val->val );
|
||||
|
||||
message_t *msg = create_message( val->exportv?SET_EXPORT:SET, key, val->val );
|
||||
msg->count=1;
|
||||
|
||||
|
||||
q_put( queue, msg );
|
||||
}
|
||||
|
||||
void enqueue_all( connection_t *c )
|
||||
{
|
||||
hash_foreach2( &env_universal_var,
|
||||
&enqueue,
|
||||
&enqueue,
|
||||
(void *)&c->unsent );
|
||||
try_send_all( c );
|
||||
}
|
||||
|
@ -974,7 +974,7 @@ void connection_init( connection_t *c, int fd )
|
|||
c->fd = fd;
|
||||
b_init( &c->input );
|
||||
q_init( &c->unsent );
|
||||
c->buffer_consumed = c->buffer_used = 0;
|
||||
c->buffer_consumed = c->buffer_used = 0;
|
||||
}
|
||||
|
||||
void connection_destroy( connection_t *c)
|
||||
|
|
|
@ -76,9 +76,9 @@ typedef struct connection
|
|||
newline is encountered, the buffer is parsed and cleared.
|
||||
*/
|
||||
buffer_t input;
|
||||
|
||||
|
||||
/**
|
||||
The read buffer.
|
||||
The read buffer.
|
||||
*/
|
||||
char buffer[ENV_UNIVERSAL_BUFFER_SIZE];
|
||||
|
||||
|
@ -86,12 +86,12 @@ typedef struct connection
|
|||
Number of bytes that have already been consumed.
|
||||
*/
|
||||
int buffer_consumed;
|
||||
|
||||
|
||||
/**
|
||||
Number of bytes that have been read into the buffer.
|
||||
Number of bytes that have been read into the buffer.
|
||||
*/
|
||||
int buffer_used;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Link to the next connection
|
||||
|
@ -103,7 +103,7 @@ typedef struct connection
|
|||
/**
|
||||
A struct representing a message to be sent between client and server
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
Number of queues that contain this message. Once this reaches zero, the message should be deleted
|
||||
|
@ -160,10 +160,10 @@ void env_universal_common_get_names( array_list_t *l,
|
|||
Do not call this function. Create a message to do it. This function
|
||||
is only to be used when fishd is dead.
|
||||
*/
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export );
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int exportv );
|
||||
|
||||
/**
|
||||
Remove the specified variable.
|
||||
Remove the specified variable.
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
|
|
212
event.cpp
212
event.cpp
|
@ -44,11 +44,11 @@ typedef struct
|
|||
/**
|
||||
Whether signals have been skipped
|
||||
*/
|
||||
int overflow;
|
||||
int overflow;
|
||||
/**
|
||||
Array of signal events
|
||||
*/
|
||||
int signal[SIG_UNHANDLED_MAX];
|
||||
int signal[SIG_UNHANDLED_MAX];
|
||||
}
|
||||
signal_list_t;
|
||||
|
||||
|
@ -84,52 +84,52 @@ static array_list_t *blocked;
|
|||
they must name the same function.
|
||||
|
||||
*/
|
||||
static int event_match( event_t *class, event_t *instance )
|
||||
static int event_match( event_t *classv, event_t *instance )
|
||||
{
|
||||
|
||||
if( class->function_name && instance->function_name )
|
||||
if( classv->function_name && instance->function_name )
|
||||
{
|
||||
if( wcscmp( class->function_name, instance->function_name ) != 0 )
|
||||
if( wcscmp( classv->function_name, instance->function_name ) != 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( class->type == EVENT_ANY )
|
||||
if( classv->type == EVENT_ANY )
|
||||
return 1;
|
||||
|
||||
if( class->type != instance->type )
|
||||
|
||||
if( classv->type != instance->type )
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
switch( class->type )
|
||||
switch( classv->type )
|
||||
{
|
||||
|
||||
|
||||
case EVENT_SIGNAL:
|
||||
if( class->param1.signal == EVENT_ANY_SIGNAL )
|
||||
if( classv->param1.signal == EVENT_ANY_SIGNAL )
|
||||
return 1;
|
||||
return class->param1.signal == instance->param1.signal;
|
||||
|
||||
return classv->param1.signal == instance->param1.signal;
|
||||
|
||||
case EVENT_VARIABLE:
|
||||
return wcscmp( instance->param1.variable,
|
||||
class->param1.variable )==0;
|
||||
|
||||
classv->param1.variable )==0;
|
||||
|
||||
case EVENT_EXIT:
|
||||
if( class->param1.pid == EVENT_ANY_PID )
|
||||
if( classv->param1.pid == EVENT_ANY_PID )
|
||||
return 1;
|
||||
return class->param1.pid == instance->param1.pid;
|
||||
return classv->param1.pid == instance->param1.pid;
|
||||
|
||||
case EVENT_JOB_ID:
|
||||
return class->param1.job_id == instance->param1.job_id;
|
||||
return classv->param1.job_id == instance->param1.job_id;
|
||||
|
||||
case EVENT_GENERIC:
|
||||
return wcscmp( instance->param1.param,
|
||||
class->param1.param )==0;
|
||||
classv->param1.param )==0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This should never be reached
|
||||
*/
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,11 +139,11 @@ static int event_match( event_t *class, event_t *instance )
|
|||
*/
|
||||
static event_t *event_copy( event_t *event, int copy_arguments )
|
||||
{
|
||||
event_t *e = malloc( sizeof( event_t ) );
|
||||
|
||||
event_t *e = (event_t *)malloc( sizeof( event_t ) );
|
||||
|
||||
if( !e )
|
||||
DIE_MEM();
|
||||
|
||||
|
||||
memcpy( e, event, sizeof(event_t));
|
||||
|
||||
if( e->function_name )
|
||||
|
@ -153,7 +153,7 @@ static event_t *event_copy( event_t *event, int copy_arguments )
|
|||
e->param1.variable = wcsdup( e->param1.variable );
|
||||
else if( e->type == EVENT_GENERIC )
|
||||
e->param1.param = wcsdup( e->param1.param );
|
||||
|
||||
|
||||
al_init( &e->arguments );
|
||||
if( copy_arguments )
|
||||
{
|
||||
|
@ -162,9 +162,9 @@ static event_t *event_copy( event_t *event, int copy_arguments )
|
|||
{
|
||||
al_push( &e->arguments, wcsdup( (wchar_t *)al_get( &event->arguments, i ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ static int event_is_blocked( event_t *e )
|
|||
{
|
||||
block_t *block;
|
||||
event_block_t *eb;
|
||||
|
||||
|
||||
for( block = current_block; block; block = block->outer )
|
||||
{
|
||||
for( eb = block->first_event_block; eb; eb=eb->next )
|
||||
|
@ -193,9 +193,9 @@ static int event_is_blocked( event_t *e )
|
|||
if( eb->type & (1<<e->type) )
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -217,18 +217,18 @@ const wchar_t *event_get_desc( event_t *e )
|
|||
{
|
||||
sb_clear( get_desc_buff );
|
||||
}
|
||||
|
||||
|
||||
switch( e->type )
|
||||
{
|
||||
|
||||
|
||||
case EVENT_SIGNAL:
|
||||
sb_printf( get_desc_buff, _(L"signal handler for %ls (%ls)"), sig2wcs(e->param1.signal ), signal_get_desc( e->param1.signal ) );
|
||||
break;
|
||||
|
||||
|
||||
case EVENT_VARIABLE:
|
||||
sb_printf( get_desc_buff, _(L"handler for variable '%ls'"), e->param1.variable );
|
||||
break;
|
||||
|
||||
|
||||
case EVENT_EXIT:
|
||||
if( e->param1.pid > 0 )
|
||||
{
|
||||
|
@ -242,9 +242,9 @@ const wchar_t *event_get_desc( event_t *e )
|
|||
else
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job with process group %d"), -e->param1.pid );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case EVENT_JOB_ID:
|
||||
{
|
||||
job_t *j = job_get( e->param1.job_id );
|
||||
|
@ -255,17 +255,17 @@ const wchar_t *event_get_desc( event_t *e )
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EVENT_GENERIC:
|
||||
sb_printf( get_desc_buff, _(L"handler for generic event '%ls'"), e->param1.param );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
sb_printf( get_desc_buff, _(L"Unknown event type") );
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return (const wchar_t *)get_desc_buff->buff;
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ void event_add_handler( event_t *event )
|
|||
event_t *e;
|
||||
|
||||
CHECK( event, );
|
||||
|
||||
|
||||
e = event_copy( event, 0 );
|
||||
|
||||
if( !events )
|
||||
|
@ -285,8 +285,8 @@ void event_add_handler( event_t *event )
|
|||
{
|
||||
signal_handle( e->param1.signal, 1 );
|
||||
}
|
||||
|
||||
al_push( events, e );
|
||||
|
||||
al_push( events, e );
|
||||
}
|
||||
|
||||
void event_remove( event_t *criterion )
|
||||
|
@ -294,7 +294,7 @@ void event_remove( event_t *criterion )
|
|||
int i;
|
||||
array_list_t *new_list=0;
|
||||
event_t e;
|
||||
|
||||
|
||||
CHECK( criterion, );
|
||||
|
||||
/*
|
||||
|
@ -305,19 +305,19 @@ void event_remove( event_t *criterion )
|
|||
that shouldn't be killed to new_list, and then drops the empty
|
||||
events-list.
|
||||
*/
|
||||
|
||||
|
||||
if( !events )
|
||||
return;
|
||||
|
||||
for( i=0; i<al_get_count( events); i++ )
|
||||
{
|
||||
event_t *n = (event_t *)al_get( events, i );
|
||||
event_t *n = (event_t *)al_get( events, i );
|
||||
if( event_match( criterion, n ) )
|
||||
{
|
||||
if( !killme )
|
||||
killme = al_new();
|
||||
|
||||
al_push( killme, n );
|
||||
|
||||
al_push( killme, n );
|
||||
|
||||
/*
|
||||
If this event was a signal handler and no other handler handles
|
||||
|
@ -329,11 +329,11 @@ void event_remove( event_t *criterion )
|
|||
e.type = EVENT_SIGNAL;
|
||||
e.param1.signal = n->param1.signal;
|
||||
e.function_name = 0;
|
||||
|
||||
|
||||
if( event_get( &e, 0 ) == 1 )
|
||||
{
|
||||
signal_handle( e.param1.signal, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -344,7 +344,7 @@ void event_remove( event_t *criterion )
|
|||
}
|
||||
}
|
||||
al_destroy( events );
|
||||
free( events );
|
||||
free( events );
|
||||
events = new_list;
|
||||
}
|
||||
|
||||
|
@ -352,21 +352,21 @@ int event_get( event_t *criterion, array_list_t *out )
|
|||
{
|
||||
int i;
|
||||
int found = 0;
|
||||
|
||||
|
||||
if( !events )
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
CHECK( criterion, 0 );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( events); i++ )
|
||||
{
|
||||
event_t *n = (event_t *)al_get( events, i );
|
||||
event_t *n = (event_t *)al_get( events, i );
|
||||
if( event_match(criterion, n ) )
|
||||
{
|
||||
found++;
|
||||
if( out )
|
||||
al_push( out, n );
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ static void event_free_kills()
|
|||
int i;
|
||||
if( !killme )
|
||||
return;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( killme ); i++ )
|
||||
{
|
||||
event_t *roadkill = (event_t *)al_get( killme, i );
|
||||
|
@ -396,16 +396,16 @@ static int event_is_killed( event_t *e )
|
|||
int i;
|
||||
if( !killme )
|
||||
return 0;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( killme ); i++ )
|
||||
{
|
||||
event_t *roadkill = (event_t *)al_get( events, i );
|
||||
if( roadkill ==e )
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Perform the specified event. Since almost all event firings will
|
||||
|
@ -418,11 +418,11 @@ static void event_fire_internal( event_t *event )
|
|||
int i, j;
|
||||
string_buffer_t *b=0;
|
||||
array_list_t *fire=0;
|
||||
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
*/
|
||||
event_free_kills();
|
||||
event_free_kills();
|
||||
|
||||
if( !events )
|
||||
return;
|
||||
|
@ -437,7 +437,7 @@ static void event_fire_internal( event_t *event )
|
|||
for( i=0; i<al_get_count( events ); i++ )
|
||||
{
|
||||
event_t *criterion = (event_t *)al_get( events, i );
|
||||
|
||||
|
||||
/*
|
||||
Check if this event is a match
|
||||
*/
|
||||
|
@ -448,17 +448,17 @@ static void event_fire_internal( event_t *event )
|
|||
al_push( fire, criterion );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
No matches. Time to return.
|
||||
*/
|
||||
if( !fire )
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
Iterate over our list of matching events
|
||||
*/
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( fire ); i++ )
|
||||
{
|
||||
event_t *criterion = (event_t *)al_get( fire, i );
|
||||
|
@ -477,19 +477,19 @@ static void event_fire_internal( event_t *event )
|
|||
b = sb_new();
|
||||
else
|
||||
sb_clear( b );
|
||||
|
||||
|
||||
sb_append( b, criterion->function_name );
|
||||
|
||||
|
||||
for( j=0; j<al_get_count(&event->arguments); j++ )
|
||||
{
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 1 );
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 1 );
|
||||
sb_append( b, L" " );
|
||||
sb_append( b, arg_esc );
|
||||
free( arg_esc );
|
||||
free( arg_esc );
|
||||
}
|
||||
|
||||
// debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff );
|
||||
|
||||
|
||||
/*
|
||||
Event handlers are not part of the main flow of code, so
|
||||
they are marked as non-interactive
|
||||
|
@ -500,27 +500,27 @@ static void event_fire_internal( event_t *event )
|
|||
current_block->param1.event = event;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
parser_pop_block();
|
||||
proc_pop_interactive();
|
||||
proc_pop_interactive();
|
||||
proc_set_last_status( prev_status );
|
||||
}
|
||||
|
||||
if( b )
|
||||
{
|
||||
sb_destroy( b );
|
||||
free( b );
|
||||
free( b );
|
||||
}
|
||||
|
||||
|
||||
if( fire )
|
||||
{
|
||||
al_destroy( fire );
|
||||
free( fire );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Free killed events
|
||||
*/
|
||||
event_free_kills();
|
||||
|
||||
event_free_kills();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -532,7 +532,7 @@ static void event_fire_delayed()
|
|||
int i;
|
||||
|
||||
/*
|
||||
If is_event is one, we are running the event-handler non-recursively.
|
||||
If is_event is one, we are running the event-handler non-recursively.
|
||||
|
||||
When the event handler has called a piece of code that triggers
|
||||
another event, we do not want to fire delayed events because of
|
||||
|
@ -541,7 +541,7 @@ static void event_fire_delayed()
|
|||
if( blocked && is_event==1)
|
||||
{
|
||||
array_list_t *new_blocked = 0;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( blocked ); i++ )
|
||||
{
|
||||
event_t *e = (event_t *)al_get( blocked, i );
|
||||
|
@ -549,24 +549,24 @@ static void event_fire_delayed()
|
|||
{
|
||||
if( !new_blocked )
|
||||
new_blocked = al_new();
|
||||
al_push( new_blocked, e );
|
||||
al_push( new_blocked, e );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( e );
|
||||
event_free( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
al_destroy( blocked );
|
||||
free( blocked );
|
||||
blocked = new_blocked;
|
||||
}
|
||||
|
||||
|
||||
while( sig_list[active_list].count > 0 )
|
||||
{
|
||||
signal_list_t *lst;
|
||||
event_t e;
|
||||
al_init( &e.arguments );
|
||||
al_init( &e.arguments );
|
||||
|
||||
/*
|
||||
Switch signal lists
|
||||
|
@ -576,47 +576,47 @@ static void event_fire_delayed()
|
|||
active_list=1-active_list;
|
||||
|
||||
/*
|
||||
Set up
|
||||
Set up
|
||||
*/
|
||||
e.type=EVENT_SIGNAL;
|
||||
e.function_name=0;
|
||||
|
||||
|
||||
lst = &sig_list[1-active_list];
|
||||
|
||||
|
||||
if( lst->overflow )
|
||||
{
|
||||
debug( 0, _( L"Signal list overflow. Signals have been ignored." ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Send all signals in our private list
|
||||
*/
|
||||
for( i=0; i<lst->count; i++ )
|
||||
{
|
||||
e.param1.signal = lst->signal[i];
|
||||
al_set( &e.arguments, 0, sig2wcs( e.param1.signal ) );
|
||||
al_set( &e.arguments, 0, sig2wcs( e.param1.signal ) );
|
||||
if( event_is_blocked( &e ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
al_push( blocked, event_copy(&e, 1) );
|
||||
al_push( blocked, event_copy(&e, 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( &e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_destroy( &e.arguments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void event_fire( event_t *event )
|
||||
{
|
||||
is_event++;
|
||||
|
||||
|
||||
if( event && (event->type == EVENT_SIGNAL) )
|
||||
{
|
||||
/*
|
||||
|
@ -636,14 +636,14 @@ void event_fire( event_t *event )
|
|||
Fire events triggered by signals
|
||||
*/
|
||||
event_fire_delayed();
|
||||
|
||||
|
||||
if( event )
|
||||
{
|
||||
if( event_is_blocked( event ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
|
||||
|
||||
al_push( blocked, event_copy(event, 1) );
|
||||
}
|
||||
else
|
||||
|
@ -651,8 +651,8 @@ void event_fire( event_t *event )
|
|||
event_fire_internal( event );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
is_event--;
|
||||
}
|
||||
|
||||
|
@ -668,7 +668,7 @@ void event_destroy()
|
|||
{
|
||||
al_foreach( events, (void (*)(void *))&event_free );
|
||||
al_destroy( events );
|
||||
free( events );
|
||||
free( events );
|
||||
events=0;
|
||||
}
|
||||
|
||||
|
@ -676,9 +676,9 @@ void event_destroy()
|
|||
{
|
||||
al_foreach( killme, (void (*)(void *))&event_free );
|
||||
al_destroy( killme );
|
||||
free( killme );
|
||||
killme=0;
|
||||
}
|
||||
free( killme );
|
||||
killme=0;
|
||||
}
|
||||
}
|
||||
|
||||
void event_free( event_t *e )
|
||||
|
@ -711,11 +711,11 @@ void event_fire_generic_internal(const wchar_t *name, ...)
|
|||
wchar_t *arg;
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
|
||||
ev.type = EVENT_GENERIC;
|
||||
ev.param1.param = name;
|
||||
ev.function_name=0;
|
||||
|
||||
|
||||
al_init( &ev.arguments );
|
||||
va_start( va, name );
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
|
@ -723,9 +723,9 @@ void event_fire_generic_internal(const wchar_t *name, ...)
|
|||
al_push( &ev.arguments, arg );
|
||||
}
|
||||
va_end( va );
|
||||
|
||||
|
||||
event_fire( &ev );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
18
event.h
18
event.h
|
@ -7,7 +7,7 @@
|
|||
functions produce output or perform memory allocations, since
|
||||
such functions may not be safely called by signal handlers.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#ifndef FISH_EVENT_H
|
||||
#define FISH_EVENT_H
|
||||
|
@ -44,7 +44,7 @@ enum
|
|||
- When used as a parameter to event_add, it represents a class of events, and function_name is the name of the function which will be called whenever an event matching the specified class occurs. This is also how events are stored internally.
|
||||
- When used as a parameter to event_get, event_remove and event_fire, it represents a class of events, and if the function_name field is non-zero, only events which call the specified function will be returned.
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
Type of event
|
||||
|
@ -78,13 +78,13 @@ typedef struct
|
|||
The parameter describing this generic event
|
||||
*/
|
||||
const wchar_t *param;
|
||||
|
||||
|
||||
} param1;
|
||||
|
||||
/**
|
||||
The name of the event handler function
|
||||
*/
|
||||
const wchar_t *function_name;
|
||||
const wchar_t *function_name;
|
||||
|
||||
/**
|
||||
The argument list. Only used when sending a new event using
|
||||
|
@ -96,28 +96,28 @@ typedef struct
|
|||
event_t;
|
||||
|
||||
/**
|
||||
Add an event handler
|
||||
Add an event handler
|
||||
|
||||
May not be called by a signal handler, since it may allocate new memory.
|
||||
*/
|
||||
void event_add_handler( event_t *event );
|
||||
|
||||
/**
|
||||
Remove all events matching the specified criterion.
|
||||
Remove all events matching the specified criterion.
|
||||
|
||||
May not be called by a signal handler, since it may free allocated memory.
|
||||
*/
|
||||
void event_remove( event_t *event );
|
||||
|
||||
/**
|
||||
Return all events which match the specified event class
|
||||
Return all events which match the specified event class
|
||||
|
||||
This function is safe to call from a signal handler _ONLY_ if the
|
||||
out parameter is null.
|
||||
|
||||
\param criterion Is the class of events to return. If the criterion has a non-null function_name, only events which trigger the specified function will return.
|
||||
\param out the list to add events to. May be 0, in which case no events will be added, but the result count will still be valid
|
||||
|
||||
|
||||
\return the number of found matches
|
||||
*/
|
||||
int event_get( event_t *criterion, array_list_t *out );
|
||||
|
@ -164,7 +164,7 @@ const wchar_t *event_get_desc( event_t *e );
|
|||
/**
|
||||
Fire a generic event with the specified name
|
||||
*/
|
||||
#define event_fire_generic( ... ) event_fire_generic_internal( __VA_ARGS__, (void *)0 )
|
||||
#define event_fire_generic( ... ) event_fire_generic_internal( __VA_ARGS__, NULL )
|
||||
|
||||
void event_fire_generic_internal(const wchar_t *name,...);
|
||||
|
||||
|
|
8
exec.h
8
exec.h
|
@ -9,9 +9,11 @@
|
|||
#define FISH_EXEC_H
|
||||
|
||||
#include <wchar.h>
|
||||
#include <vector>
|
||||
|
||||
#include "proc.h"
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
pipe redirection error message
|
||||
|
@ -19,7 +21,7 @@
|
|||
#define PIPE_ERROR _(L"An error occurred while setting up pipe")
|
||||
|
||||
/**
|
||||
Execute the processes specified by j.
|
||||
Execute the processes specified by j.
|
||||
|
||||
I've put a fair bit of work into making builtins behave like other
|
||||
programs as far as pipes are concerned. Unlike i.e. bash, builtins
|
||||
|
@ -51,9 +53,11 @@ void exec( job_t *j );
|
|||
|
||||
\return the status of the last job to exit, or -1 if en error was encountered.
|
||||
*/
|
||||
__warn_unused int exec_subshell( const wchar_t *cmd,
|
||||
__warn_unused int exec_subshell( const wchar_t *cmd,
|
||||
array_list_t *l );
|
||||
|
||||
__warn_unused int exec_subshell2( const wcstring &cmd, std::vector<wcstring> &outputs );
|
||||
|
||||
|
||||
/**
|
||||
Loops over close until thesyscall was run without beeing
|
||||
|
|
809
expand.cpp
809
expand.cpp
File diff suppressed because it is too large
Load diff
27
expand.h
27
expand.h
|
@ -6,7 +6,7 @@
|
|||
benefit from using a more clever memory allocation scheme, perhaps
|
||||
an evil combination of talloc, string buffers and reference
|
||||
counting.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FISH_EXPAND_H
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include <wchar.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
Flag specifying that cmdsubst expansion should be skipped
|
||||
|
@ -70,7 +72,7 @@ enum
|
|||
|
||||
/** Character represeting process expansion */
|
||||
PROCESS_EXPAND,
|
||||
|
||||
|
||||
/** Character representing variable expansion */
|
||||
VARIABLE_EXPAND,
|
||||
|
||||
|
@ -86,7 +88,7 @@ enum
|
|||
/** Character representing separation between two bracket elements */
|
||||
BRACKET_SEP,
|
||||
/**
|
||||
Separate subtokens in a token with this character.
|
||||
Separate subtokens in a token with this character.
|
||||
*/
|
||||
INTERNAL_SEPARATOR,
|
||||
|
||||
|
@ -128,7 +130,7 @@ enum
|
|||
(\$VAR_NAME becomes the value of the environment variable VAR_NAME),
|
||||
cmdsubst expansion and wildcard expansion. The results are inserted
|
||||
into the list out.
|
||||
|
||||
|
||||
If the parameter does not need expansion, it is copied into the list
|
||||
out. If expansion is performed, the original parameter is freed and
|
||||
newly allocated strings are inserted into the list out.
|
||||
|
@ -136,7 +138,7 @@ enum
|
|||
If \c context is non-null, all the strings contained in the
|
||||
array_list_t \c out will be registered to be free'd when context is
|
||||
free'd.
|
||||
|
||||
|
||||
\param context the halloc context to use for automatic deallocation
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
|
@ -144,6 +146,7 @@ enum
|
|||
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH. EXPAND_WILDCARD_NO_MATCH and EXPAND_WILDCARD_MATCH are normal exit conditions used only on strings containing wildcards to tell if the wildcard produced any matches.
|
||||
*/
|
||||
__warn_unused int expand_string( void *context, wchar_t *in, array_list_t *out, int flag );
|
||||
__warn_unused int expand_string2( const wcstring &input, std::list<wcstring> &output, int flag );
|
||||
|
||||
/**
|
||||
expand_one is identical to expand_string, except it will fail if in
|
||||
|
@ -152,8 +155,8 @@ __warn_unused int expand_string( void *context, wchar_t *in, array_list_t *out,
|
|||
|
||||
If \c context is non-null, the returning string ill be registered
|
||||
to be free'd when context is free'd.
|
||||
|
||||
\param context the halloc context to use for automatic deallocation
|
||||
|
||||
\param context the halloc context to use for automatic deallocation
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\return The expanded parameter, or 0 on failiure
|
||||
|
@ -168,14 +171,12 @@ wchar_t *expand_one( void *context, wchar_t *in, int flag );
|
|||
wchar_t *expand_escape_variable( const wchar_t *in );
|
||||
|
||||
/**
|
||||
Perform tilde expansion and nothing else on the specified string.
|
||||
Perform tilde expansion and nothing else on the specified string, which is modified in place.
|
||||
|
||||
If tilde expansion is needed, the original string is freed and a
|
||||
new string, allocated using malloc, is returned.
|
||||
|
||||
\param in the string to tilde expand
|
||||
\param input the string to tilde expand
|
||||
*/
|
||||
wchar_t *expand_tilde(wchar_t *in);
|
||||
void expand_tilde(wcstring &input);
|
||||
wchar_t * expand_tilde_compat( wchar_t *input );
|
||||
|
||||
|
||||
/**
|
||||
|
|
244
fallback.cpp
244
fallback.cpp
|
@ -60,7 +60,7 @@ int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t))
|
|||
while( *str )
|
||||
{
|
||||
fish_putc( *str++ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -81,26 +81,26 @@ char *tparm_solaris_kludge( char *str, ... )
|
|||
|
||||
if( ( set_a_foreground && ! strcmp( str, set_a_foreground ) )
|
||||
|| ( set_a_background && ! strcmp( str, set_a_background ) )
|
||||
|| ( set_foreground && ! strcmp( str, set_foreground ) )
|
||||
|| ( set_foreground && ! strcmp( str, set_foreground ) )
|
||||
|| ( set_background && ! strcmp( str, set_background ) )
|
||||
|| ( enter_underline_mode && ! strcmp( str, enter_underline_mode ) )
|
||||
|| ( exit_underline_mode && ! strcmp( str, exit_underline_mode ) )
|
||||
|| ( enter_standout_mode && ! strcmp( str, enter_standout_mode ) )
|
||||
|| ( exit_standout_mode && ! strcmp( str, exit_standout_mode ) )
|
||||
|| ( flash_screen && ! strcmp( str, flash_screen ) )
|
||||
|| ( enter_subscript_mode && ! strcmp( str, enter_subscript_mode ) )
|
||||
|| ( exit_subscript_mode && ! strcmp( str, exit_subscript_mode ) )
|
||||
|| ( enter_superscript_mode && ! strcmp( str, enter_superscript_mode ) )
|
||||
|| ( exit_superscript_mode && ! strcmp( str, exit_superscript_mode ) )
|
||||
|| ( enter_blink_mode && ! strcmp( str, enter_blink_mode ) )
|
||||
|| ( enter_italics_mode && ! strcmp( str, enter_italics_mode ) )
|
||||
|| ( exit_italics_mode && ! strcmp( str, exit_italics_mode ) )
|
||||
|| ( enter_reverse_mode && ! strcmp( str, enter_reverse_mode ) )
|
||||
|| ( enter_shadow_mode && ! strcmp( str, enter_shadow_mode ) )
|
||||
|| ( exit_shadow_mode && ! strcmp( str, exit_shadow_mode ) )
|
||||
|| ( enter_standout_mode && ! strcmp( str, enter_standout_mode ) )
|
||||
|| ( exit_standout_mode && ! strcmp( str, exit_standout_mode ) )
|
||||
|| ( enter_secure_mode && ! strcmp( str, enter_secure_mode ) )
|
||||
|| ( enter_underline_mode && ! strcmp( str, enter_underline_mode ) )
|
||||
|| ( exit_underline_mode && ! strcmp( str, exit_underline_mode ) )
|
||||
|| ( enter_standout_mode && ! strcmp( str, enter_standout_mode ) )
|
||||
|| ( exit_standout_mode && ! strcmp( str, exit_standout_mode ) )
|
||||
|| ( flash_screen && ! strcmp( str, flash_screen ) )
|
||||
|| ( enter_subscript_mode && ! strcmp( str, enter_subscript_mode ) )
|
||||
|| ( exit_subscript_mode && ! strcmp( str, exit_subscript_mode ) )
|
||||
|| ( enter_superscript_mode && ! strcmp( str, enter_superscript_mode ) )
|
||||
|| ( exit_superscript_mode && ! strcmp( str, exit_superscript_mode ) )
|
||||
|| ( enter_blink_mode && ! strcmp( str, enter_blink_mode ) )
|
||||
|| ( enter_italics_mode && ! strcmp( str, enter_italics_mode ) )
|
||||
|| ( exit_italics_mode && ! strcmp( str, exit_italics_mode ) )
|
||||
|| ( enter_reverse_mode && ! strcmp( str, enter_reverse_mode ) )
|
||||
|| ( enter_shadow_mode && ! strcmp( str, enter_shadow_mode ) )
|
||||
|| ( exit_shadow_mode && ! strcmp( str, exit_shadow_mode ) )
|
||||
|| ( enter_standout_mode && ! strcmp( str, enter_standout_mode ) )
|
||||
|| ( exit_standout_mode && ! strcmp( str, exit_standout_mode ) )
|
||||
|| ( enter_secure_mode && ! strcmp( str, enter_secure_mode ) )
|
||||
|| ( enter_bold_mode && ! strcmp ( str, enter_bold_mode ) ) )
|
||||
{
|
||||
param[0] = va_arg( ap, long int );
|
||||
|
@ -140,11 +140,11 @@ char *tparm_solaris_kludge( char *str, ... )
|
|||
*/
|
||||
static void pad( void (*writer)(wchar_t), int count)
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
if( count < 0 )
|
||||
return;
|
||||
|
||||
|
||||
for( i=0; i<count; i++ )
|
||||
{
|
||||
writer( L' ' );
|
||||
|
@ -171,13 +171,13 @@ static void pad( void (*writer)(wchar_t), int count)
|
|||
|
||||
For a full description on the usage of *printf, see use 'man 3 printf'.
|
||||
*/
|
||||
static int vgwprintf( void (*writer)(wchar_t),
|
||||
const wchar_t *filter,
|
||||
static int vgwprintf( void (*writer)(wchar_t),
|
||||
const wchar_t *filter,
|
||||
va_list va )
|
||||
{
|
||||
const wchar_t *filter_org=filter;
|
||||
int count=0;
|
||||
|
||||
|
||||
for( ;*filter; filter++)
|
||||
{
|
||||
if(*filter == L'%')
|
||||
|
@ -188,19 +188,19 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
int loop=1;
|
||||
int precision=-1;
|
||||
int pad_left = 1;
|
||||
|
||||
|
||||
if( iswdigit( *filter ) )
|
||||
{
|
||||
width=0;
|
||||
while( (*filter >= L'0') && (*filter <= L'9'))
|
||||
{
|
||||
width=10*width+(*filter++ - L'0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while( loop )
|
||||
{
|
||||
|
||||
|
||||
switch(*filter)
|
||||
{
|
||||
case L'l':
|
||||
|
@ -219,9 +219,9 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
filter++;
|
||||
pad_left=0;
|
||||
break;
|
||||
|
||||
|
||||
case L'.':
|
||||
/*
|
||||
/*
|
||||
Set precision.
|
||||
*/
|
||||
filter++;
|
||||
|
@ -235,10 +235,10 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
while( (*filter >= L'0') && (*filter <= L'9'))
|
||||
{
|
||||
precision=10*precision+(*filter++ - L'0');
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
loop=0;
|
||||
break;
|
||||
|
@ -253,8 +253,8 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
|
||||
if( (width >= 0) && pad_left )
|
||||
{
|
||||
pad( writer, width-1 );
|
||||
count += maxi( width-1, 0 );
|
||||
pad( writer, width-1 );
|
||||
count += maxi( width-1, 0 );
|
||||
}
|
||||
|
||||
c = is_long?va_arg(va, wint_t):btowc(va_arg(va, int));
|
||||
|
@ -265,16 +265,16 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
if( (width >= 0) && !pad_left )
|
||||
{
|
||||
pad( writer, width-1 );
|
||||
count += maxi( width-1, 0 );
|
||||
count += maxi( width-1, 0 );
|
||||
}
|
||||
|
||||
|
||||
count++;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case L's':
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
wchar_t *ss=0;
|
||||
if( is_long )
|
||||
{
|
||||
|
@ -287,41 +287,41 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
if( ns )
|
||||
{
|
||||
ss = str2wcs( ns );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !ss )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( (width >= 0) && pad_left )
|
||||
{
|
||||
pad( writer, width-wcslen(ss) );
|
||||
count += maxi(width-wcslen(ss), 0);
|
||||
pad( writer, width-wcslen(ss) );
|
||||
count += maxi(width-wcslen(ss), 0);
|
||||
}
|
||||
|
||||
|
||||
wchar_t *s=ss;
|
||||
int precount = count;
|
||||
|
||||
|
||||
while( *s )
|
||||
{
|
||||
if( (precision > 0) && (precision <= (count-precount) ) )
|
||||
break;
|
||||
|
||||
|
||||
writer( *(s++) );
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
if( (width >= 0) && !pad_left )
|
||||
{
|
||||
pad( writer, width-wcslen(ss) );
|
||||
count += maxi( width-wcslen(ss), 0 );
|
||||
pad( writer, width-wcslen(ss) );
|
||||
count += maxi( width-wcslen(ss), 0 );
|
||||
}
|
||||
|
||||
|
||||
if( !is_long )
|
||||
free( ss );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -336,7 +336,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
char *pos;
|
||||
char format[16];
|
||||
int len;
|
||||
|
||||
|
||||
format[0]=0;
|
||||
strcat( format, "%");
|
||||
if( precision >= 0 )
|
||||
|
@ -350,7 +350,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
strcat( format, "l" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
len = strlen(format);
|
||||
format[len++]=(char)*filter;
|
||||
format[len]=0;
|
||||
|
@ -360,7 +360,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
case L'd':
|
||||
case L'i':
|
||||
{
|
||||
|
||||
|
||||
switch( is_long )
|
||||
{
|
||||
case 0:
|
||||
|
@ -370,10 +370,10 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, precision, d );
|
||||
else
|
||||
snprintf( str, 32, format, d );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
long d = va_arg( va, long );
|
||||
|
@ -383,7 +383,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, d );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
long long d = va_arg( va, long long );
|
||||
|
@ -393,21 +393,21 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, d );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
debug( 0, L"Invalid length modifier in string %ls\n", filter_org );
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
case L'u':
|
||||
case L'o':
|
||||
case L'x':
|
||||
case L'X':
|
||||
{
|
||||
|
||||
|
||||
switch( is_long )
|
||||
{
|
||||
case 0:
|
||||
|
@ -419,7 +419,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, d );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
unsigned long d = va_arg( va, unsigned long );
|
||||
|
@ -429,7 +429,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, d );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
unsigned long long d = va_arg( va, unsigned long long );
|
||||
|
@ -439,43 +439,43 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
snprintf( str, 32, format, d );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
debug( 0, L"Invalid length modifier in string %ls\n", filter_org );
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
debug( 0, L"Invalid filter %ls in string %ls\n", *filter, filter_org );
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( (width >= 0) && pad_left )
|
||||
{
|
||||
int l = maxi(width-strlen(str), 0 );
|
||||
pad( writer, l );
|
||||
count += l;
|
||||
}
|
||||
|
||||
|
||||
pos = str;
|
||||
|
||||
|
||||
while( *pos )
|
||||
{
|
||||
writer( *(pos++) );
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
if( (width >= 0) && !pad_left )
|
||||
{
|
||||
int l = maxi(width-strlen(str), 0 );
|
||||
pad( writer, l );
|
||||
count += l;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
char str[32];
|
||||
char *pos;
|
||||
double val = va_arg( va, double );
|
||||
|
||||
|
||||
if( precision>= 0 )
|
||||
{
|
||||
if( width>= 0 )
|
||||
|
@ -509,21 +509,21 @@ static int vgwprintf( void (*writer)(wchar_t),
|
|||
}
|
||||
|
||||
pos = str;
|
||||
|
||||
|
||||
while( *pos )
|
||||
{
|
||||
writer( *(pos++) );
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case L'n':
|
||||
{
|
||||
int *n = va_arg( va, int *);
|
||||
|
||||
*n = count;
|
||||
|
||||
*n = count;
|
||||
break;
|
||||
}
|
||||
case L'%':
|
||||
|
@ -564,14 +564,14 @@ sw_data;
|
|||
static void sw_writer( wchar_t c )
|
||||
{
|
||||
if( sw_data.count < sw_data.max )
|
||||
*(sw_data.pos++)=c;
|
||||
*(sw_data.pos++)=c;
|
||||
sw_data.count++;
|
||||
}
|
||||
|
||||
int vswprintf( wchar_t *out, size_t n, const wchar_t *filter, va_list va )
|
||||
{
|
||||
int written;
|
||||
|
||||
|
||||
sw_data.pos=out;
|
||||
sw_data.max=n;
|
||||
sw_data.count=0;
|
||||
|
@ -586,7 +586,7 @@ int vswprintf( wchar_t *out, size_t n, const wchar_t *filter, va_list va )
|
|||
{
|
||||
written=-1;
|
||||
}
|
||||
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
|
@ -594,7 +594,7 @@ int swprintf( wchar_t *out, size_t n, const wchar_t *filter, ... )
|
|||
{
|
||||
va_list va;
|
||||
int written;
|
||||
|
||||
|
||||
va_start( va, filter );
|
||||
written = vswprintf( out, n, filter, va );
|
||||
va_end( va );
|
||||
|
@ -624,7 +624,7 @@ int fwprintf( FILE *f, const wchar_t *filter, ... )
|
|||
{
|
||||
va_list va;
|
||||
int written;
|
||||
|
||||
|
||||
va_start( va, filter );
|
||||
written = vfwprintf( f, filter, va );
|
||||
va_end( va );
|
||||
|
@ -640,7 +640,7 @@ int wprintf( const wchar_t *filter, ... )
|
|||
{
|
||||
va_list va;
|
||||
int written;
|
||||
|
||||
|
||||
va_start( va, filter );
|
||||
written=vwprintf( filter, va );
|
||||
va_end( va );
|
||||
|
@ -661,16 +661,16 @@ wint_t fgetwc(FILE *stream)
|
|||
{
|
||||
int b = fgetc( stream );
|
||||
char bb;
|
||||
|
||||
|
||||
int sz;
|
||||
|
||||
|
||||
if( b == EOF )
|
||||
return WEOF;
|
||||
|
||||
bb=b;
|
||||
|
||||
|
||||
sz = mbrtowc( &res, &bb, 1, &state );
|
||||
|
||||
|
||||
switch( sz )
|
||||
{
|
||||
case -1:
|
||||
|
@ -733,13 +733,13 @@ static size_t fish_wcsspn (const wchar_t *wcs,
|
|||
for (a = accept; *a != L'\0'; ++a)
|
||||
if (*p == *a)
|
||||
break;
|
||||
|
||||
|
||||
if (*a == L'\0')
|
||||
return count;
|
||||
else
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -752,7 +752,7 @@ static wchar_t *fish_wcspbrk (const wchar_t *wcs, const wchar_t *accept)
|
|||
++wcs;
|
||||
else
|
||||
return (wchar_t *) wcs;
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -775,18 +775,18 @@ wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr)
|
|||
|
||||
/* Scan leading delimiters. */
|
||||
wcs += fish_wcsspn (wcs, delim);
|
||||
|
||||
|
||||
if (*wcs == L'\0')
|
||||
{
|
||||
*save_ptr = NULL;
|
||||
*save_ptr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the end of the token. */
|
||||
result = wcs;
|
||||
|
||||
|
||||
wcs = fish_wcspbrk (result, delim);
|
||||
|
||||
|
||||
if (wcs == NULL)
|
||||
{
|
||||
/* This token finishes the string. */
|
||||
|
@ -807,7 +807,7 @@ wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr)
|
|||
wchar_t *wcsdup( const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
wchar_t *out = malloc( sizeof( wchar_t)*(len+1));
|
||||
wchar_t *out = (wchar_t *)malloc( sizeof( wchar_t)*(len+1));
|
||||
if( out == 0 )
|
||||
{
|
||||
return 0;
|
||||
|
@ -815,7 +815,7 @@ wchar_t *wcsdup( const wchar_t *in )
|
|||
|
||||
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
||||
return out;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -855,7 +855,7 @@ int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count )
|
|||
{
|
||||
if( count == 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
if( *a == 0 )
|
||||
{
|
||||
return (*b==0)?0:-1;
|
||||
|
@ -886,13 +886,13 @@ int wcwidth( wchar_t c )
|
|||
#ifndef HAVE_WCSNDUP
|
||||
wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
wchar_t *res = malloc( sizeof(wchar_t)*(c+1) );
|
||||
wchar_t *res = (wchar_t *)malloc( sizeof(wchar_t)*(c+1) );
|
||||
if( res == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
wcslcpy( res, in, c+1 );
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -905,22 +905,22 @@ long convert_digit( wchar_t d, int base )
|
|||
}
|
||||
else if( (d <= L'z') && (d >= L'a') )
|
||||
{
|
||||
res = d + 10 - L'a';
|
||||
res = d + 10 - L'a';
|
||||
}
|
||||
else if( (d <= L'Z') && (d >= L'A') )
|
||||
{
|
||||
res = d + 10 - L'A';
|
||||
res = d + 10 - L'A';
|
||||
}
|
||||
if( res >= base )
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef HAVE_WCSTOL
|
||||
long wcstol(const wchar_t *nptr,
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base)
|
||||
{
|
||||
|
@ -943,7 +943,7 @@ long wcstol(const wchar_t *nptr,
|
|||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
res = (res*base)+nxt;
|
||||
is_set = 1;
|
||||
|
@ -985,25 +985,25 @@ long wcstol(const wchar_t *nptr,
|
|||
size_t
|
||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
|
||||
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
|
||||
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + wcslen(s));
|
||||
|
||||
while (*s != '\0')
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (n != 1)
|
||||
if (n != 1)
|
||||
{
|
||||
*d++ = *s;
|
||||
n--;
|
||||
|
@ -1043,12 +1043,12 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
|||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -1056,8 +1056,8 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
|||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0)
|
||||
*d = '\0';
|
||||
/* NUL-terminate dst */
|
||||
|
@ -1074,7 +1074,7 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
|||
|
||||
int lrand48_r(struct drand48_data *buffer, long int *result)
|
||||
{
|
||||
*result = rand_r( &buffer->seed );
|
||||
*result = rand_r( &buffer->seed );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1143,10 +1143,10 @@ int killpg( int pgr, int sig )
|
|||
|
||||
#ifndef HAVE_WORKING_GETOPT_LONG
|
||||
|
||||
int getopt_long( int argc,
|
||||
int getopt_long( int argc,
|
||||
char * const argv[],
|
||||
const char *optstring,
|
||||
const struct option *longopts,
|
||||
const struct option *longopts,
|
||||
int *longindex )
|
||||
{
|
||||
return getopt( argc, argv, optstring );
|
||||
|
@ -1181,7 +1181,7 @@ long sysconf(int name)
|
|||
}
|
||||
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
18
fallback.h
18
fallback.h
|
@ -57,12 +57,12 @@ typedef char tputs_arg_t;
|
|||
/**
|
||||
Structure used to get the size of a terminal window
|
||||
*/
|
||||
struct winsize
|
||||
struct winsize
|
||||
{
|
||||
/**
|
||||
Number of rows
|
||||
*/
|
||||
unsigned short ws_row;
|
||||
unsigned short ws_row;
|
||||
/**
|
||||
Number of columns
|
||||
*/
|
||||
|
@ -193,7 +193,7 @@ wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
|
|||
/**
|
||||
Return the number of columns used by a character. This is a libc
|
||||
function, but the prototype for this function is missing in some libc
|
||||
implementations.
|
||||
implementations.
|
||||
|
||||
Fish has a fallback implementation in case the implementation is
|
||||
missing altogether. In locales without a native wcwidth, Unicode
|
||||
|
@ -320,7 +320,7 @@ size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
|||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
|
@ -390,7 +390,7 @@ char * textdomain( const char * domainname );
|
|||
/**
|
||||
Fallback implementation of dcgettext. Just returns the original string.
|
||||
*/
|
||||
char * dcgettext ( const char * domainname,
|
||||
char * dcgettext ( const char * domainname,
|
||||
const char * msgid,
|
||||
int category );
|
||||
|
||||
|
@ -421,7 +421,7 @@ int killpg( int pgr, int sig );
|
|||
/**
|
||||
Struct describing a long getopt option
|
||||
*/
|
||||
struct option
|
||||
struct option
|
||||
{
|
||||
/**
|
||||
Name of option
|
||||
|
@ -438,7 +438,7 @@ struct option
|
|||
/**
|
||||
Return value
|
||||
*/
|
||||
int val;
|
||||
int val;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -454,10 +454,10 @@ struct option
|
|||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
int getopt_long(int argc,
|
||||
int getopt_long(int argc,
|
||||
char * const argv[],
|
||||
const char *optstring,
|
||||
const struct option *longopts,
|
||||
const struct option *longopts,
|
||||
int *longindex);
|
||||
|
||||
#endif
|
||||
|
|
128
fish.cpp
128
fish.cpp
|
@ -80,7 +80,7 @@ static int read_init()
|
|||
|
||||
eval( L"builtin . " DATADIR "/fish/config.fish 2>/dev/null", 0, TOP );
|
||||
eval( L"builtin . " SYSCONFDIR L"/fish/config.fish 2>/dev/null", 0, TOP );
|
||||
|
||||
|
||||
/*
|
||||
We need to get the configuration directory before we can source the user configuration file
|
||||
*/
|
||||
|
@ -99,9 +99,9 @@ static int read_init()
|
|||
eval( (wchar_t *)eval_buff->buff, 0, TOP );
|
||||
free( config_dir_escaped );
|
||||
}
|
||||
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -114,83 +114,83 @@ static int fish_parse_opt( int argc, char **argv, char **cmd_ptr )
|
|||
{
|
||||
int my_optind;
|
||||
int force_interactive=0;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
"command", required_argument, 0, 'c'
|
||||
"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
"debug-level", required_argument, 0, 'd'
|
||||
"debug-level", required_argument, 0, 'd'
|
||||
}
|
||||
,
|
||||
{
|
||||
"interactive", no_argument, 0, 'i'
|
||||
"interactive", no_argument, 0, 'i'
|
||||
}
|
||||
,
|
||||
{
|
||||
"login", no_argument, 0, 'l'
|
||||
"login", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
"no-execute", no_argument, 0, 'n'
|
||||
"no-execute", no_argument, 0, 'n'
|
||||
}
|
||||
,
|
||||
{
|
||||
"profile", required_argument, 0, 'p'
|
||||
"profile", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
|
||||
case 'c':
|
||||
{
|
||||
*cmd_ptr = optarg;
|
||||
*cmd_ptr = optarg;
|
||||
is_interactive_session = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'd':
|
||||
|
||||
case 'd':
|
||||
{
|
||||
char *end;
|
||||
int tmp;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtol(optarg, &end, 10);
|
||||
|
||||
|
||||
if( tmp >= 0 && tmp <=10 && !*end && !errno )
|
||||
{
|
||||
debug_level=tmp;
|
||||
|
@ -202,65 +202,65 @@ static int fish_parse_opt( int argc, char **argv, char **cmd_ptr )
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'h':
|
||||
{
|
||||
*cmd_ptr = "__fish_print_help fish";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'i':
|
||||
{
|
||||
force_interactive = 1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'l':
|
||||
{
|
||||
is_login=1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'n':
|
||||
{
|
||||
no_exec=1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'p':
|
||||
{
|
||||
profile = optarg;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'v':
|
||||
{
|
||||
fwprintf( stderr,
|
||||
_(L"%s, version %s\n"),
|
||||
fwprintf( stderr,
|
||||
_(L"%s, version %s\n"),
|
||||
PACKAGE_NAME,
|
||||
PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
case '?':
|
||||
{
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
my_optind = optind;
|
||||
|
||||
|
||||
is_login |= (strcmp( argv[0], "-fish") == 0);
|
||||
|
||||
|
||||
/*
|
||||
We are an interactive session if we have not been given an
|
||||
explicit command to execute, _and_ stdin is a tty.
|
||||
*/
|
||||
is_interactive_session &= (*cmd_ptr == 0);
|
||||
is_interactive_session &= (my_optind == argc);
|
||||
is_interactive_session &= isatty(STDIN_FILENO);
|
||||
is_interactive_session &= isatty(STDIN_FILENO);
|
||||
|
||||
/*
|
||||
We are also an interactive session if we have are forced-
|
||||
|
@ -282,7 +282,7 @@ int main( int argc, char **argv )
|
|||
char *cmd=0;
|
||||
int my_optind=0;
|
||||
|
||||
halloc_util_init();
|
||||
halloc_util_init();
|
||||
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
is_interactive_session=1;
|
||||
|
@ -299,9 +299,9 @@ int main( int argc, char **argv )
|
|||
debug( 1, _(L"Can not use the no-execute mode when running an interactive session") );
|
||||
no_exec = 0;
|
||||
}
|
||||
|
||||
proc_init();
|
||||
event_init();
|
||||
|
||||
proc_init();
|
||||
event_init();
|
||||
wutil_init();
|
||||
parser_init();
|
||||
builtin_init();
|
||||
|
@ -327,13 +327,13 @@ int main( int argc, char **argv )
|
|||
}
|
||||
else
|
||||
{
|
||||
char **ptr;
|
||||
char **ptr;
|
||||
char *file = *(argv+(my_optind++));
|
||||
int i;
|
||||
int i;
|
||||
string_buffer_t sb;
|
||||
int fd;
|
||||
wchar_t *rel_filename, *abs_filename;
|
||||
|
||||
|
||||
if( ( fd = open(file, O_RDONLY) ) == -1 )
|
||||
{
|
||||
wperror( L"open" );
|
||||
|
@ -343,7 +343,7 @@ int main( int argc, char **argv )
|
|||
if( *(argv+my_optind))
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
|
||||
for( i=1,ptr = argv+my_optind; *ptr; i++, ptr++ )
|
||||
{
|
||||
if( i != 1 )
|
||||
|
@ -352,7 +352,7 @@ int main( int argc, char **argv )
|
|||
sb_append( &sb, val );
|
||||
free( val );
|
||||
}
|
||||
|
||||
|
||||
env_set( L"argv", (wchar_t *)sb.buff, 0 );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
|
@ -373,17 +373,17 @@ int main( int argc, char **argv )
|
|||
|
||||
if( res )
|
||||
{
|
||||
debug( 1,
|
||||
_(L"Error while reading file %ls\n"),
|
||||
debug( 1,
|
||||
_(L"Error while reading file %ls\n"),
|
||||
reader_current_filename()?reader_current_filename(): _(L"Standard input") );
|
||||
}
|
||||
}
|
||||
reader_pop_current_filename();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
|
||||
history_destroy();
|
||||
proc_destroy();
|
||||
builtin_destroy();
|
||||
|
@ -392,12 +392,12 @@ int main( int argc, char **argv )
|
|||
parser_destroy();
|
||||
wutil_destroy();
|
||||
event_destroy();
|
||||
|
||||
|
||||
halloc_util_destroy();
|
||||
|
||||
|
||||
env_destroy();
|
||||
|
||||
|
||||
intern_free_all();
|
||||
|
||||
return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status();
|
||||
|
||||
return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status();
|
||||
}
|
||||
|
|
144
fish_indent.cpp
144
fish_indent.cpp
|
@ -64,10 +64,10 @@ static void read_file( FILE *f, string_buffer_t *b )
|
|||
wperror(L"fgetwc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
sb_append_char( b, c );
|
||||
}
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ static void read_file( FILE *f, string_buffer_t *b )
|
|||
static void insert_tabs( string_buffer_t *out, int indent )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<indent; i++ )
|
||||
{
|
||||
sb_append( out, L"\t" );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,12 +100,12 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
int prev_prev_type = 0;
|
||||
|
||||
tok_init( &tok, in, TOK_SHOW_COMMENTS );
|
||||
|
||||
|
||||
for( ; tok_has_next( &tok ); tok_next( &tok ) )
|
||||
{
|
||||
int type = tok_last_type( &tok );
|
||||
wchar_t *last = tok_last( &tok );
|
||||
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case TOK_STRING:
|
||||
|
@ -116,7 +116,7 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
is_command = 0;
|
||||
|
||||
wchar_t *unesc = unescape( last, UNESCAPE_SPECIAL );
|
||||
|
||||
|
||||
if( parser_keywords_is_block( unesc ) )
|
||||
{
|
||||
next_indent++;
|
||||
|
@ -135,17 +135,17 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
indent--;
|
||||
next_indent--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if( do_indent && flags && prev_type != TOK_PIPE )
|
||||
{
|
||||
insert_tabs( out, indent );
|
||||
}
|
||||
|
||||
|
||||
sb_printf( out, L"%ls", last );
|
||||
|
||||
|
||||
indent = next_indent;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -153,13 +153,13 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
sb_append( out, L" " );
|
||||
sb_append( out, last );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOK_END:
|
||||
{
|
||||
if( prev_type != TOK_END || prev_prev_type != TOK_END )
|
||||
if( prev_type != TOK_END || prev_prev_type != TOK_END )
|
||||
sb_append( out, L"\n" );
|
||||
do_indent = 1;
|
||||
is_command = 1;
|
||||
|
@ -174,11 +174,11 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
} else if ( last[0] != '1' || last[1] ) {
|
||||
sb_append( out, last, L">" );
|
||||
}
|
||||
sb_append( out, L"| " );
|
||||
sb_append( out, L" | " );
|
||||
is_command = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOK_REDIRECT_OUT:
|
||||
{
|
||||
sb_append( out, L" " );
|
||||
|
@ -186,13 +186,13 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
sb_append( out, L"^" );
|
||||
} else {
|
||||
if ( wcscmp( last, L"1" ) != 0 )
|
||||
sb_append( out, last );
|
||||
sb_append( out, L">" );
|
||||
sb_append( out, last );
|
||||
sb_append( out, L"> " );
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case TOK_REDIRECT_APPEND:
|
||||
|
||||
case TOK_REDIRECT_APPEND:
|
||||
{
|
||||
sb_append( out, L" " );
|
||||
if ( wcscmp( last, L"2" ) == 0 ) {
|
||||
|
@ -200,28 +200,28 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
} else {
|
||||
if ( wcscmp( last, L"1" ) != 0 )
|
||||
sb_append( out, last );
|
||||
sb_append( out, L">>" );
|
||||
sb_append( out, L">> " );
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case TOK_REDIRECT_IN:
|
||||
|
||||
case TOK_REDIRECT_IN:
|
||||
{
|
||||
sb_append( out, L" " );
|
||||
if ( wcscmp( last, L"0" ) != 0 )
|
||||
sb_append( out, last );
|
||||
sb_append( out, L"<" );
|
||||
break;
|
||||
sb_append( out, L"< " );
|
||||
break;
|
||||
}
|
||||
|
||||
case TOK_REDIRECT_FD:
|
||||
|
||||
case TOK_REDIRECT_FD:
|
||||
{
|
||||
sb_append( out, L" " );
|
||||
if ( wcscmp( last, L"1" ) != 0 )
|
||||
sb_append( out, last );
|
||||
sb_append( out, L">&" );
|
||||
break;
|
||||
}
|
||||
sb_append( out, L">& " );
|
||||
break;
|
||||
}
|
||||
|
||||
case TOK_BACKGROUND:
|
||||
{
|
||||
|
@ -230,31 +230,31 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
is_command = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TOK_COMMENT:
|
||||
{
|
||||
if( do_indent && flags)
|
||||
{
|
||||
insert_tabs( out, indent );
|
||||
}
|
||||
|
||||
|
||||
sb_printf( out, L"%ls", last );
|
||||
do_indent = 1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
debug( 0, L"Unknown token '%ls'", last );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prev_prev_type = prev_type;
|
||||
prev_type = type;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
return res;
|
||||
|
@ -268,27 +268,27 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
|
|||
static wchar_t *trim( wchar_t *in )
|
||||
{
|
||||
wchar_t *end;
|
||||
|
||||
|
||||
while( *in == L'\n' )
|
||||
{
|
||||
in++;
|
||||
}
|
||||
|
||||
|
||||
end = in + wcslen(in);
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( end < in+2 )
|
||||
break;
|
||||
|
||||
end--;
|
||||
|
||||
|
||||
if( (*end == L'\n' ) && ( *(end-1) == L'\n' ) )
|
||||
*end=0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
@ -300,9 +300,9 @@ int main( int argc, char **argv )
|
|||
{
|
||||
string_buffer_t sb_in;
|
||||
string_buffer_t sb_out;
|
||||
|
||||
|
||||
int do_indent=1;
|
||||
|
||||
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
program_name=L"fish_indent";
|
||||
|
||||
|
@ -312,55 +312,55 @@ int main( int argc, char **argv )
|
|||
long_options[] =
|
||||
{
|
||||
{
|
||||
"no-indent", no_argument, 0, 'i'
|
||||
"no-indent", no_argument, 0, 'i'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'h':
|
||||
{
|
||||
print_help( "fish_indent", 1 );
|
||||
exit( 0 );
|
||||
exit( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'v':
|
||||
{
|
||||
fwprintf( stderr,
|
||||
_(L"%ls, version %s\n"),
|
||||
fwprintf( stderr,
|
||||
_(L"%ls, version %s\n"),
|
||||
program_name,
|
||||
PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
case 'i':
|
||||
|
@ -368,23 +368,23 @@ int main( int argc, char **argv )
|
|||
do_indent = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
case '?':
|
||||
{
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
halloc_util_init();
|
||||
halloc_util_init();
|
||||
|
||||
sb_init( &sb_in );
|
||||
sb_init( &sb_out );
|
||||
|
||||
read_file( stdin, &sb_in );
|
||||
|
||||
|
||||
wutil_init();
|
||||
|
||||
if( !indent( &sb_out, (wchar_t *)sb_in.buff, do_indent ) )
|
||||
|
@ -398,7 +398,7 @@ int main( int argc, char **argv )
|
|||
*/
|
||||
fwprintf( stdout, L"%ls", (wchar_t *)sb_in.buff );
|
||||
}
|
||||
|
||||
|
||||
|
||||
wutil_destroy();
|
||||
|
||||
|
|
264
fish_pager.cpp
264
fish_pager.cpp
|
@ -61,7 +61,7 @@
|
|||
#include "halloc_util.h"
|
||||
#include "print_help.h"
|
||||
|
||||
enum
|
||||
enum
|
||||
{
|
||||
LINE_UP = R_NULL+1,
|
||||
LINE_DOWN,
|
||||
|
@ -146,7 +146,7 @@ static buffer_t *pager_buffer;
|
|||
The environment variables used to specify the color of different
|
||||
tokens.
|
||||
*/
|
||||
static wchar_t *hightlight_var[] =
|
||||
static wchar_t *hightlight_var[] =
|
||||
{
|
||||
L"fish_pager_color_prefix",
|
||||
L"fish_pager_color_completion",
|
||||
|
@ -167,7 +167,7 @@ static FILE *out_file;
|
|||
/**
|
||||
Data structure describing one or a group of related completions
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
The list of all completin strings this entry applies to
|
||||
|
@ -180,11 +180,11 @@ typedef struct
|
|||
/**
|
||||
On-screen width of the completion string
|
||||
*/
|
||||
int comp_width;
|
||||
int comp_width;
|
||||
/**
|
||||
On-screen width of the description information
|
||||
*/
|
||||
int desc_width;
|
||||
int desc_width;
|
||||
/**
|
||||
Preffered total width
|
||||
*/
|
||||
|
@ -208,20 +208,20 @@ static int get_color( int highlight )
|
|||
return FISH_COLOR_NORMAL;
|
||||
if( highlight >= (4) )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
|
||||
val = wgetenv( hightlight_var[highlight]);
|
||||
|
||||
if( !val )
|
||||
{
|
||||
val = env_universal_get( hightlight_var[highlight]);
|
||||
}
|
||||
|
||||
|
||||
if( !val )
|
||||
{
|
||||
return FISH_COLOR_NORMAL;
|
||||
}
|
||||
|
||||
return output_color_code( val );
|
||||
|
||||
return output_color_code( val );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,11 +236,11 @@ static void recalc_width( array_list_t *l, const wchar_t *prefix )
|
|||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
comp_t *c = (comp_t *)al_get( l, i );
|
||||
|
||||
|
||||
c->min_width = mini( c->desc_width, maxi(0,termsize.ws_col/3 - 2)) +
|
||||
mini( c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,14 +251,14 @@ static int try_sequence( char *seq )
|
|||
{
|
||||
int j, k;
|
||||
wint_t c=0;
|
||||
|
||||
for( j=0;
|
||||
seq[j] != '\0' && seq[j] == (c=input_common_readch( j>0 ));
|
||||
|
||||
for( j=0;
|
||||
seq[j] != '\0' && seq[j] == (c=input_common_readch( j>0 ));
|
||||
j++ )
|
||||
;
|
||||
|
||||
if( seq[j] == '\0' )
|
||||
{
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
@ -281,10 +281,10 @@ static wint_t readch()
|
|||
wint_t bnd;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
struct mapping m[]=
|
||||
{
|
||||
{
|
||||
{
|
||||
"\x1b[A", LINE_UP
|
||||
}
|
||||
,
|
||||
|
@ -292,7 +292,7 @@ static wint_t readch()
|
|||
key_up, LINE_UP
|
||||
}
|
||||
,
|
||||
{
|
||||
{
|
||||
"\x1b[B", LINE_DOWN
|
||||
}
|
||||
,
|
||||
|
@ -319,18 +319,18 @@ static wint_t readch()
|
|||
{
|
||||
0, 0
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
;
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; m[i].bnd; i++ )
|
||||
{
|
||||
if( !m[i].seq )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( try_sequence(m[i].seq ) )
|
||||
return m[i].bnd;
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ static int print_max( const wchar_t *str, int max, int has_more )
|
|||
int written = 0;
|
||||
for( i=0; str[i]; i++ )
|
||||
{
|
||||
|
||||
|
||||
if( written + wcwidth(str[i]) > max )
|
||||
break;
|
||||
if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) )
|
||||
|
@ -378,7 +378,7 @@ static int print_max( const wchar_t *str, int max, int has_more )
|
|||
written += wcwidth(ellipsis_char );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
writech( str[i] );
|
||||
written+= wcwidth( str[i] );
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
|
|||
int comp_width=0, desc_width=0;
|
||||
int i;
|
||||
int written=0;
|
||||
|
||||
|
||||
if( c->pref_width <= width )
|
||||
{
|
||||
/*
|
||||
|
@ -411,7 +411,7 @@ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
|
|||
the description.
|
||||
*/
|
||||
int desc_all = c->desc_width?c->desc_width+4:0;
|
||||
|
||||
|
||||
comp_width = maxi( mini( c->comp_width,
|
||||
2*(width-4)/3 ),
|
||||
width - desc_all );
|
||||
|
@ -419,9 +419,9 @@ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
|
|||
desc_width = width-comp_width-4;
|
||||
else
|
||||
c->desc_width=0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( c->comp ); i++ )
|
||||
{
|
||||
const wchar_t *comp = (const wchar_t *)al_get( c->comp, i );
|
||||
|
@ -455,7 +455,7 @@ static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
|
|||
writech( L' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,14 +490,14 @@ static void completion_print( int cols,
|
|||
comp_t *el;
|
||||
|
||||
int is_last = (j==(cols-1));
|
||||
|
||||
|
||||
if( al_get_count( l ) <= j*rows + i )
|
||||
continue;
|
||||
|
||||
el = (comp_t *)al_get( l, j*rows + i );
|
||||
|
||||
|
||||
completion_print_item( prefix, el, width[j] - (is_last?0:2) );
|
||||
|
||||
|
||||
if( !is_last)
|
||||
writestr( L" " );
|
||||
}
|
||||
|
@ -545,24 +545,24 @@ static int completion_try_print( int cols,
|
|||
Set to one if the list should be printed at this width
|
||||
*/
|
||||
int print=0;
|
||||
|
||||
|
||||
int i, j;
|
||||
|
||||
|
||||
int rows = (al_get_count( l )-1)/cols+1;
|
||||
|
||||
|
||||
int pref_tot_width=0;
|
||||
int min_tot_width = 0;
|
||||
int res=PAGER_RETRY;
|
||||
/*
|
||||
Skip completions on tiny terminals
|
||||
*/
|
||||
|
||||
|
||||
if( termsize.ws_col < PAGER_MIN_WIDTH )
|
||||
return PAGER_DONE;
|
||||
|
||||
|
||||
memset( pref_width, 0, sizeof(pref_width) );
|
||||
memset( min_width, 0, sizeof(min_width) );
|
||||
|
||||
|
||||
/* Calculate how wide the list would be */
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
|
@ -576,7 +576,7 @@ static int completion_try_print( int cols,
|
|||
c = (comp_t *)al_get( l, j*rows + i );
|
||||
pref = c->pref_width;
|
||||
min = c->min_width;
|
||||
|
||||
|
||||
if( j != cols-1 )
|
||||
{
|
||||
pref += 2;
|
||||
|
@ -632,7 +632,7 @@ static int completion_try_print( int cols,
|
|||
be helped, but it is not uncommon for the completions to
|
||||
_almost_ fit on one screen. In those cases, it is almost
|
||||
always desirable to 'squeeze' the completions into a
|
||||
single page.
|
||||
single page.
|
||||
|
||||
If we are using N columns and can get everything to
|
||||
fit using squeezing, but everything would also fit
|
||||
|
@ -668,7 +668,7 @@ static int completion_try_print( int cols,
|
|||
is_ca_mode = 0;
|
||||
writembs(exit_ca_mode);
|
||||
}
|
||||
|
||||
|
||||
completion_print( cols, width, 0, rows, prefix, is_quoted, l);
|
||||
pager_flush();
|
||||
}
|
||||
|
@ -687,7 +687,7 @@ static int completion_try_print( int cols,
|
|||
is_ca_mode=1;
|
||||
writembs(enter_ca_mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
completion_print( cols,
|
||||
width,
|
||||
|
@ -704,18 +704,18 @@ static int completion_try_print( int cols,
|
|||
{
|
||||
string_buffer_t msg;
|
||||
sb_init( &msg );
|
||||
|
||||
|
||||
set_color( FISH_COLOR_BLACK,
|
||||
get_color(HIGHLIGHT_PAGER_PROGRESS) );
|
||||
sb_printf( &msg,
|
||||
_(L" %d to %d of %d"),
|
||||
pos,
|
||||
pos+termsize.ws_row-1,
|
||||
pos+termsize.ws_row-1,
|
||||
rows );
|
||||
|
||||
|
||||
sb_printf( &msg,
|
||||
L" \r" );
|
||||
|
||||
|
||||
writestr((wchar_t *)msg.buff);
|
||||
sb_destroy( &msg );
|
||||
set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL );
|
||||
|
@ -817,15 +817,15 @@ static int completion_try_print( int cols,
|
|||
do_loop=0;
|
||||
res=PAGER_RESIZE;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
sb_append_char( &out_buff, c );
|
||||
do_loop = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
writembs(clr_eol);
|
||||
|
@ -847,31 +847,31 @@ static void mangle_descriptions( array_list_t *l )
|
|||
wchar_t *next = (wchar_t *)al_get(l, i);
|
||||
wchar_t *in, *out;
|
||||
skip=1;
|
||||
|
||||
|
||||
while( *next != COMPLETE_SEP && *next )
|
||||
next++;
|
||||
|
||||
|
||||
if( !*next )
|
||||
continue;
|
||||
|
||||
|
||||
in=out=(next+1);
|
||||
|
||||
|
||||
while( *in != 0 )
|
||||
{
|
||||
if( *in == L' ' || *in==L'\t' || *in<32 )
|
||||
{
|
||||
if( !skip )
|
||||
*out++=L' ';
|
||||
skip=1;
|
||||
skip=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = *in;
|
||||
*out++ = *in;
|
||||
skip=0;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
*out=0;
|
||||
*out=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +883,7 @@ static void join_completions( array_list_t *l )
|
|||
long i;
|
||||
int in, out;
|
||||
hash_table_t desc_table;
|
||||
|
||||
|
||||
hash_init( &desc_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
for( i=0; i<al_get_count(l); i++ )
|
||||
|
@ -891,7 +891,7 @@ static void join_completions( array_list_t *l )
|
|||
wchar_t *item = (wchar_t *)al_get( l, i );
|
||||
wchar_t *desc = wcschr( item, COMPLETE_SEP );
|
||||
long prev_idx;
|
||||
|
||||
|
||||
if( !desc )
|
||||
continue;
|
||||
desc++;
|
||||
|
@ -905,11 +905,11 @@ static void join_completions( array_list_t *l )
|
|||
string_buffer_t foo;
|
||||
wchar_t *old = (wchar_t *)al_get( l, prev_idx );
|
||||
wchar_t *old_end = wcschr( old, COMPLETE_SEP );
|
||||
|
||||
|
||||
if( old_end )
|
||||
{
|
||||
*old_end = 0;
|
||||
|
||||
|
||||
sb_init( &foo );
|
||||
sb_append( &foo, old );
|
||||
sb_append_char( &foo, COMPLETE_ITEM_SEP );
|
||||
|
@ -921,23 +921,23 @@ static void join_completions( array_list_t *l )
|
|||
free( (void *)al_get( l, i ) );
|
||||
al_set( l, i, 0 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
hash_destroy( &desc_table );
|
||||
|
||||
out=0;
|
||||
for( in=0; in < al_get_count(l); in++ )
|
||||
{
|
||||
const void * d = al_get( l, in );
|
||||
|
||||
|
||||
if( d )
|
||||
{
|
||||
al_set( l, out++, d );
|
||||
}
|
||||
}
|
||||
al_truncate( l, out );
|
||||
al_truncate( l, out );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -946,23 +946,23 @@ static void join_completions( array_list_t *l )
|
|||
static void mangle_completions( array_list_t *l, const wchar_t *prefix )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( l, i );
|
||||
wchar_t *start, *end;
|
||||
comp_t *comp = halloc( global_context, sizeof( comp_t ) );
|
||||
comp_t *comp = (comp_t *)halloc( global_context, sizeof( comp_t ) );
|
||||
comp->comp = al_halloc( global_context );
|
||||
|
||||
|
||||
for( start=end=next; 1; end++ )
|
||||
{
|
||||
wchar_t c = *end;
|
||||
|
||||
|
||||
if( (c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c)
|
||||
{
|
||||
*end = 0;
|
||||
wchar_t * str = escape( start, ESCAPE_ALL | ESCAPE_NO_QUOTED );
|
||||
|
||||
|
||||
comp->comp_width += my_wcswidth( str );
|
||||
halloc_register( global_context, str );
|
||||
al_push( comp->comp, str );
|
||||
|
@ -973,22 +973,22 @@ static void mangle_completions( array_list_t *l, const wchar_t *prefix )
|
|||
{
|
||||
comp->desc = halloc_wcsdup( global_context, start );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( !c )
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
comp->comp_width += my_wcswidth(prefix)*al_get_count(comp->comp) + 2*(al_get_count(comp->comp)-1);
|
||||
comp->desc_width = comp->desc?my_wcswidth( comp->desc ):0;
|
||||
|
||||
|
||||
comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0);
|
||||
|
||||
|
||||
free( next );
|
||||
al_set( l, i, comp );
|
||||
}
|
||||
|
||||
|
||||
recalc_width( l, prefix );
|
||||
}
|
||||
|
||||
|
@ -1026,10 +1026,10 @@ static void init( int mangle_descriptors, int out )
|
|||
|
||||
static struct termios pager_modes;
|
||||
char *term;
|
||||
|
||||
|
||||
if( mangle_descriptors )
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
Make fd 1 output to screen, and use some other fd for writing
|
||||
the resulting output back to the caller
|
||||
|
@ -1042,13 +1042,13 @@ static void init( int mangle_descriptors, int out )
|
|||
if( (in = open( ttyname(2), O_RDWR )) != -1 )
|
||||
{
|
||||
if( dup2( 2, 1 ) == -1 )
|
||||
{
|
||||
{
|
||||
debug( 0, _(L"Could not set up output file descriptors for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
if( dup2( in, 0 ) == -1 )
|
||||
{
|
||||
{
|
||||
debug( 0, _(L"Could not set up input file descriptors for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
@ -1059,13 +1059,13 @@ static void init( int mangle_descriptors, int out )
|
|||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !(out_file = fdopen( out, "w" )) )
|
||||
{
|
||||
debug( 0, _(L"Could not initialize result pipe" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Init the stringbuffer used to keep any output in
|
||||
|
@ -1075,7 +1075,7 @@ static void init( int mangle_descriptors, int out )
|
|||
env_universal_init( 0, 0, 0, 0);
|
||||
input_common_init( &interrupt_handler );
|
||||
output_set_writer( &pager_buffered_writer );
|
||||
pager_buffer = halloc( global_context, sizeof( buffer_t ) );
|
||||
pager_buffer = (buffer_t *)halloc( global_context, sizeof( buffer_t ) );
|
||||
halloc_register_function( global_context, (void (*)(void *))&b_destroy, pager_buffer );
|
||||
|
||||
sigemptyset( & act.sa_mask );
|
||||
|
@ -1088,7 +1088,7 @@ static void init( int mangle_descriptors, int out )
|
|||
wperror( L"sigaction" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
handle_winch( 0 ); /* Set handler for window change events */
|
||||
|
||||
tcgetattr(0,&pager_modes); /* get the current terminal modes */
|
||||
|
@ -1102,14 +1102,14 @@ static void init( int mangle_descriptors, int out )
|
|||
pager_modes.c_cc[VTIME]=0;
|
||||
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( setupterm( 0, STDOUT_FILENO, 0) == ERR )
|
||||
{
|
||||
|
@ -1124,7 +1124,7 @@ static void init( int mangle_descriptors, int out )
|
|||
output_set_term( wterm );
|
||||
free( wterm );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1137,9 +1137,9 @@ static void destroy()
|
|||
wutil_destroy();
|
||||
if( del_curterm( cur_term ) == ERR )
|
||||
{
|
||||
debug( 0, _(L"Error while closing terminfo") );
|
||||
debug( 0, _(L"Error while closing terminfo") );
|
||||
}
|
||||
|
||||
|
||||
sb_destroy( &out_buff );
|
||||
fclose( out_file );
|
||||
}
|
||||
|
@ -1164,7 +1164,7 @@ static void read_array( FILE* file, array_list_t *comp )
|
|||
while( 1 )
|
||||
{
|
||||
c = getc( file );
|
||||
if( c == EOF )
|
||||
if( c == EOF )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1175,7 +1175,7 @@ static void read_array( FILE* file, array_list_t *comp )
|
|||
}
|
||||
|
||||
cc=c;
|
||||
|
||||
|
||||
b_append( &buffer, &cc, 1 );
|
||||
}
|
||||
|
||||
|
@ -1183,15 +1183,15 @@ static void read_array( FILE* file, array_list_t *comp )
|
|||
{
|
||||
cc=0;
|
||||
b_append( &buffer, &cc, 1 );
|
||||
|
||||
|
||||
wcs = str2wcs( buffer.buff );
|
||||
if( wcs )
|
||||
if( wcs )
|
||||
{
|
||||
unescaped = unescape( wcs, 0 );
|
||||
if( unescaped )
|
||||
{
|
||||
al_push( comp, unescaped );
|
||||
}
|
||||
}
|
||||
free( wcs );
|
||||
}
|
||||
}
|
||||
|
@ -1203,9 +1203,9 @@ static void read_array( FILE* file, array_list_t *comp )
|
|||
|
||||
static int get_fd( const char *str )
|
||||
{
|
||||
char *end;
|
||||
char *end;
|
||||
long fd;
|
||||
|
||||
|
||||
errno = 0;
|
||||
fd = strtol( str, &end, 10 );
|
||||
if( fd < 0 || *end || errno )
|
||||
|
@ -1220,13 +1220,13 @@ static int get_fd( const char *str )
|
|||
int main( int argc, char **argv )
|
||||
{
|
||||
int i;
|
||||
int is_quoted=0;
|
||||
int is_quoted=0;
|
||||
array_list_t *comp;
|
||||
wchar_t *prefix = 0;
|
||||
|
||||
int mangle_descriptors = 0;
|
||||
int result_fd = -1;
|
||||
|
||||
|
||||
/*
|
||||
This initialization is made early, so that the other init code
|
||||
can use global_context for memory managment
|
||||
|
@ -1252,69 +1252,69 @@ int main( int argc, char **argv )
|
|||
/*
|
||||
Third mode
|
||||
*/
|
||||
|
||||
|
||||
int completion_fd = -1;
|
||||
FILE *completion_file;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
"result-fd", required_argument, 0, 'r'
|
||||
"result-fd", required_argument, 0, 'r'
|
||||
}
|
||||
,
|
||||
{
|
||||
"completion-fd", required_argument, 0, 'c'
|
||||
"completion-fd", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
"prefix", required_argument, 0, 'p'
|
||||
"prefix", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
"is-quoted", no_argument, 0, 'q'
|
||||
"is-quoted", no_argument, 0, 'q'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'r':
|
||||
{
|
||||
result_fd = get_fd( optarg );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'c':
|
||||
{
|
||||
completion_fd = get_fd( optarg );
|
||||
|
@ -1330,20 +1330,20 @@ int main( int argc, char **argv )
|
|||
case 'h':
|
||||
{
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
case 'q':
|
||||
{
|
||||
is_quoted = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1352,7 +1352,7 @@ int main( int argc, char **argv )
|
|||
debug( 0, _(L"Unspecified file descriptors") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( (completion_file = fdopen( completion_fd, "r" ) ) )
|
||||
{
|
||||
|
@ -1370,8 +1370,8 @@ int main( int argc, char **argv )
|
|||
{
|
||||
prefix = wcsdup( L"" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1385,7 +1385,7 @@ int main( int argc, char **argv )
|
|||
forward. A reasonable time frame for removal of the code
|
||||
below has yet to be determined.
|
||||
*/
|
||||
|
||||
|
||||
if( argc < 3 )
|
||||
{
|
||||
print_help( argv[0], 1 );
|
||||
|
@ -1394,10 +1394,10 @@ int main( int argc, char **argv )
|
|||
else
|
||||
{
|
||||
mangle_descriptors = 1;
|
||||
|
||||
|
||||
prefix = str2wcs( argv[2] );
|
||||
is_quoted = strcmp( "1", argv[1] )==0;
|
||||
|
||||
|
||||
if( argc > 3 )
|
||||
{
|
||||
/*
|
||||
|
@ -1420,11 +1420,11 @@ int main( int argc, char **argv )
|
|||
read_array( stdin, comp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// debug( 3, L"prefix is '%ls'", prefix );
|
||||
|
||||
|
||||
init( mangle_descriptors, result_fd );
|
||||
|
||||
mangle_descriptions( comp );
|
||||
|
@ -1462,9 +1462,9 @@ int main( int argc, char **argv )
|
|||
i=PAGER_MAX_COLS+1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(prefix );
|
||||
|
||||
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );
|
||||
|
@ -1476,6 +1476,6 @@ int main( int argc, char **argv )
|
|||
destroy();
|
||||
|
||||
halloc_util_destroy();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
308
fish_tests.cpp
308
fish_tests.cpp
|
@ -16,7 +16,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
|
@ -80,27 +80,27 @@ static int err_count=0;
|
|||
/**
|
||||
Print formatted output
|
||||
*/
|
||||
static void say( wchar_t *blah, ... )
|
||||
static void say( const wchar_t *blah, ... )
|
||||
{
|
||||
va_list va;
|
||||
va_start( va, blah );
|
||||
vwprintf( blah, va );
|
||||
va_end( va );
|
||||
va_end( va );
|
||||
wprintf( L"\n" );
|
||||
}
|
||||
|
||||
/**
|
||||
Print formatted error string
|
||||
*/
|
||||
static void err( wchar_t *blah, ... )
|
||||
static void err( const wchar_t *blah, ... )
|
||||
{
|
||||
va_list va;
|
||||
va_start( va, blah );
|
||||
err_count++;
|
||||
|
||||
|
||||
wprintf( L"Error: " );
|
||||
vwprintf( blah, va );
|
||||
va_end( va );
|
||||
va_end( va );
|
||||
wprintf( L"\n" );
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ static void err( wchar_t *blah, ... )
|
|||
*/
|
||||
static int pq_compare( void *e1, void *e2 )
|
||||
{
|
||||
return e1-e2;
|
||||
return (intptr_t)e1-(intptr_t)e2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,13 +119,13 @@ static void pq_test( int elements )
|
|||
{
|
||||
int i;
|
||||
int prev;
|
||||
|
||||
int *count = calloc( sizeof(int), 100 );
|
||||
|
||||
|
||||
int *count = (int *)calloc( sizeof(int), 100 );
|
||||
|
||||
priority_queue_t q;
|
||||
pq_init( &q, pq_compare );
|
||||
|
||||
|
||||
|
||||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
long foo = rand() % 100;
|
||||
|
@ -133,9 +133,9 @@ static void pq_test( int elements )
|
|||
pq_put( &q, (void *)foo );
|
||||
count[foo]++;
|
||||
}
|
||||
|
||||
|
||||
prev = 100;
|
||||
|
||||
|
||||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
long pos = (long)pq_get( &q );
|
||||
|
@ -143,7 +143,7 @@ static void pq_test( int elements )
|
|||
if( pos > prev )
|
||||
err( L"Wrong order of elements in priority_queue_t" );
|
||||
prev = pos;
|
||||
|
||||
|
||||
}
|
||||
|
||||
for( i=0; i<100; i++ )
|
||||
|
@ -163,10 +163,10 @@ static int stack_test( int elements )
|
|||
long i;
|
||||
|
||||
int res=1;
|
||||
|
||||
|
||||
array_list_t s;
|
||||
|
||||
al_init( &s );
|
||||
al_init( &s );
|
||||
|
||||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
|
@ -174,11 +174,11 @@ static int stack_test( int elements )
|
|||
|
||||
al_push_long( &s, i);
|
||||
al_push_long( &s, i);
|
||||
|
||||
|
||||
if( (foo=al_pop_long( &s )) != i )
|
||||
{
|
||||
err( L"Unexpected data" );
|
||||
res = 0;
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -186,18 +186,18 @@ static int stack_test( int elements )
|
|||
for( i=0; i<elements; i++ )
|
||||
{
|
||||
long foo;
|
||||
|
||||
|
||||
if( (foo=al_pop_long( &s )) != (elements-i-1) )
|
||||
{
|
||||
err( L"Unexpected data" );
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_destroy( &s );
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ static int hash_func( void *data )
|
|||
return rand();
|
||||
*/
|
||||
int foo = (int)(long)data;
|
||||
return 127*((foo^0xefc7e214)) ^(foo<<11);
|
||||
return 127*((foo^0xefc7e214)) ^(foo<<11);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,26 +229,26 @@ static int hash_test( long elements )
|
|||
{
|
||||
long i;
|
||||
int res=1;
|
||||
|
||||
|
||||
hash_table_t h;
|
||||
|
||||
hash_init( &h, hash_func, compare_func );
|
||||
|
||||
|
||||
for( i=1; i< elements+1; i++ )
|
||||
{
|
||||
hash_put( &h, (void*)i, (void*)100l-i );
|
||||
hash_put( &h, (void*)i, (void*)(100l-i) );
|
||||
}
|
||||
|
||||
|
||||
for( i=1; i< elements+1; i++ )
|
||||
{
|
||||
if( (long)hash_get( &h, (void*)i ) != (100l-i) )
|
||||
{
|
||||
err( L"Key %d gave data %d, expected data %d",
|
||||
i,
|
||||
i,
|
||||
(long)hash_get( &h, (void*)i ),
|
||||
100l-i );
|
||||
res = 0;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -259,14 +259,14 @@ static int hash_test( long elements )
|
|||
hash_get_count( &h ),
|
||||
elements );
|
||||
res = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for( i=1; i<elements+1; i+=2 )
|
||||
{
|
||||
hash_remove( &h, (void*)i, 0, 0 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( hash_get_count( &h ) != ((elements)/2) )
|
||||
|
@ -276,7 +276,7 @@ static int hash_test( long elements )
|
|||
elements/2 );
|
||||
res = 0;
|
||||
}
|
||||
|
||||
|
||||
for( i=1; i<elements+1; i++ )
|
||||
{
|
||||
if( hash_contains( &h, (void*)i) != (i+1l)%2l )
|
||||
|
@ -295,7 +295,7 @@ static int hash_test( long elements )
|
|||
hash_destroy( &h );
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,19 +303,19 @@ static int hash_test( long elements )
|
|||
*/
|
||||
static void al_test( int sz)
|
||||
{
|
||||
long i;
|
||||
long i;
|
||||
array_list_t l;
|
||||
|
||||
|
||||
|
||||
|
||||
al_init( &l );
|
||||
|
||||
|
||||
al_set_long( &l, 1, 7L );
|
||||
al_set_long( &l, sz, 7L );
|
||||
|
||||
|
||||
if( al_get_count( &l ) != maxi( sz+1, 2 ) )
|
||||
err( L"Wrong number of elements in array list" );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &l ); i++ )
|
||||
{
|
||||
long val = al_get_long( &l, i );
|
||||
|
@ -339,15 +339,15 @@ static void sb_test()
|
|||
{
|
||||
string_buffer_t b;
|
||||
int res;
|
||||
|
||||
|
||||
sb_init( &b );
|
||||
|
||||
|
||||
if( (res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " )) == -1 )
|
||||
{
|
||||
err( L"Error %d while testing stringbuffers", res );
|
||||
}
|
||||
|
||||
if( (res=sb_printf( &b, L"%ls", L"functionality" ))==-1)
|
||||
|
||||
if( (res=sb_printf( &b, L"%ls", L"functionality" ))==-1)
|
||||
{
|
||||
err( L"Error %d while testing stringbuffers", res );
|
||||
}
|
||||
|
@ -362,9 +362,9 @@ static void sb_test()
|
|||
err( L"numerical formating is broken, '%ls' != '%ls'", (wchar_t *)b.buff, NUM_ANS );
|
||||
}
|
||||
else
|
||||
say( L"numerical formating works" );
|
||||
|
||||
say( L"numerical formating works" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,7 +375,7 @@ static void test_util()
|
|||
int i;
|
||||
|
||||
say( L"Testing utility library" );
|
||||
|
||||
|
||||
for( i=0; i<18; i++ )
|
||||
{
|
||||
long t1, t2;
|
||||
|
@ -392,27 +392,27 @@ static void test_util()
|
|||
}
|
||||
|
||||
sb_test();
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
int i;
|
||||
for( i=2; i<10000000; i*=2 )
|
||||
{
|
||||
|
||||
|
||||
printf( "%d", i );
|
||||
|
||||
|
||||
t1 = get_time();
|
||||
|
||||
|
||||
if(!hash_test(i))
|
||||
exit(0);
|
||||
|
||||
|
||||
t2 = get_time();
|
||||
|
||||
|
||||
printf( " %d\n", (t2-t1)/i );
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -424,15 +424,15 @@ static void test_escape()
|
|||
{
|
||||
int i;
|
||||
string_buffer_t sb;
|
||||
|
||||
|
||||
say( L"Testing escaping and unescaping" );
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
|
||||
for( i=0; i<ESCAPE_TEST_COUNT; i++ )
|
||||
{
|
||||
wchar_t *o, *e, *u;
|
||||
|
||||
|
||||
sb_clear( &sb );
|
||||
while( rand() % ESCAPE_TEST_LENGTH )
|
||||
{
|
||||
|
@ -444,23 +444,23 @@ static void test_escape()
|
|||
if( !o || !e || !u )
|
||||
{
|
||||
err( L"Escaping cycle of string %ls produced null pointer on %ls", o, e?L"unescaping":L"escaping" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if( wcscmp(o, u) )
|
||||
{
|
||||
err( L"Escaping cycle of string %ls produced different string %ls", o, u );
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
free( e );
|
||||
free( u );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,17 +470,17 @@ static void test_escape()
|
|||
*/
|
||||
static void test_convert()
|
||||
{
|
||||
/* char o[] =
|
||||
/* char o[] =
|
||||
{
|
||||
-17, -128, -121, -68, 0
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
wchar_t *w = str2wcs(o);
|
||||
char *n = wcs2str(w);
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; o[i]; i++ )
|
||||
{
|
||||
bitprint(o[i]);;
|
||||
|
@ -508,20 +508,20 @@ static void test_convert()
|
|||
|
||||
int i;
|
||||
buffer_t sb;
|
||||
|
||||
|
||||
say( L"Testing wide/narrow string conversion" );
|
||||
|
||||
b_init( &sb );
|
||||
|
||||
|
||||
for( i=0; i<ESCAPE_TEST_COUNT; i++ )
|
||||
{
|
||||
wchar_t *w;
|
||||
char *o, *n;
|
||||
|
||||
|
||||
char c;
|
||||
|
||||
|
||||
sb.used=0;
|
||||
|
||||
|
||||
while( rand() % ESCAPE_TEST_LENGTH )
|
||||
{
|
||||
c = rand ();
|
||||
|
@ -529,23 +529,23 @@ static void test_convert()
|
|||
}
|
||||
c = 0;
|
||||
b_append( &sb, &c, 1 );
|
||||
|
||||
|
||||
o = (char *)sb.buff;
|
||||
w = str2wcs(o);
|
||||
n = wcs2str(w);
|
||||
|
||||
|
||||
if( !o || !w || !n )
|
||||
{
|
||||
err( L"Conversion cycle of string %s produced null pointer on %s", o, w?L"str2wcs":L"wcs2str" );
|
||||
err( L"Line %d - Conversion cycle of string %s produced null pointer on %s", __LINE__, o, w?L"str2wcs":L"wcs2str" );
|
||||
}
|
||||
|
||||
|
||||
if( strcmp(o, n) )
|
||||
{
|
||||
err( L"%d: Conversion cycle of string %s produced different string %s", i, o, n );
|
||||
err( L"Line %d - %d: Conversion cycle of string %s produced different string %s", __LINE__, i, o, n );
|
||||
}
|
||||
free( w );
|
||||
free( n );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -556,10 +556,10 @@ static void test_convert()
|
|||
static void test_tok()
|
||||
{
|
||||
tokenizer t;
|
||||
|
||||
|
||||
say( L"Testing tokenizer" );
|
||||
|
||||
|
||||
|
||||
say( L"Testing invalid input" );
|
||||
tok_init( &t, 0, 0 );
|
||||
|
||||
|
@ -567,13 +567,13 @@ static void test_tok()
|
|||
{
|
||||
err(L"Invalid input to tokenizer was undetected" );
|
||||
}
|
||||
|
||||
|
||||
say( L"Testing use of broken tokenizer" );
|
||||
if( !tok_has_next( &t ) )
|
||||
{
|
||||
err( L"tok_has_next() should return 1 once on broken tokenizer" );
|
||||
}
|
||||
|
||||
|
||||
tok_next( &t );
|
||||
if( tok_last_type( &t ) != TOK_ERROR )
|
||||
{
|
||||
|
@ -585,17 +585,17 @@ static void test_tok()
|
|||
*/
|
||||
say( L"Test destruction of broken tokenizer" );
|
||||
tok_destroy( &t );
|
||||
|
||||
|
||||
{
|
||||
|
||||
wchar_t *str = L"string <redirection 2>&1 'nested \"quoted\" '(string containing subshells ){and,brackets}$as[$well (as variable arrays)]";
|
||||
const int types[] =
|
||||
const wchar_t *str = L"string <redirection 2>&1 'nested \"quoted\" '(string containing subshells ){and,brackets}$as[$well (as variable arrays)]";
|
||||
const int types[] =
|
||||
{
|
||||
TOK_STRING, TOK_REDIRECT_IN, TOK_STRING, TOK_REDIRECT_FD, TOK_STRING, TOK_STRING, TOK_END
|
||||
}
|
||||
;
|
||||
int i;
|
||||
|
||||
size_t i;
|
||||
|
||||
say( L"Test correct tokenization" );
|
||||
|
||||
for( i=0, tok_init( &t, str, 0 ); i<(sizeof(types)/sizeof(int)); i++,tok_next( &t ) )
|
||||
|
@ -603,7 +603,7 @@ static void test_tok()
|
|||
if( types[i] != tok_last_type( &t ) )
|
||||
{
|
||||
err( L"Tokenization error:");
|
||||
wprintf( L"Token number %d of string \n'%ls'\n, expected token type %ls, got token '%ls' of type %ls\n",
|
||||
wprintf( L"Token number %d of string \n'%ls'\n, expected token type %ls, got token '%ls' of type %ls\n",
|
||||
i+1,
|
||||
str,
|
||||
tok_get_desc(types[i]),
|
||||
|
@ -612,9 +612,9 @@ static void test_tok()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -623,8 +623,8 @@ static void test_tok()
|
|||
static void test_parser()
|
||||
{
|
||||
say( L"Testing parser" );
|
||||
|
||||
|
||||
|
||||
|
||||
say( L"Testing null input to parser" );
|
||||
if( !parser_test( 0, 0, 0, 0 ) )
|
||||
{
|
||||
|
@ -634,51 +634,51 @@ static void test_parser()
|
|||
say( L"Testing block nesting" );
|
||||
if( !parser_test( L"if; end", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"Incomplete if statement undetected" );
|
||||
err( L"Incomplete if statement undetected" );
|
||||
}
|
||||
if( !parser_test( L"if test; echo", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"Missing end undetected" );
|
||||
err( L"Missing end undetected" );
|
||||
}
|
||||
if( !parser_test( L"if test; end; end", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"Unbalanced end undetected" );
|
||||
err( L"Unbalanced end undetected" );
|
||||
}
|
||||
|
||||
say( L"Testing detection of invalid use of builtin commands" );
|
||||
if( !parser_test( L"case foo", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"'case' command outside of block context undetected" );
|
||||
err( L"'case' command outside of block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"switch ggg; if true; case foo;end;end", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"'case' command outside of switch block context undetected" );
|
||||
err( L"'case' command outside of switch block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"else", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"'else' command outside of conditional block context undetected" );
|
||||
err( L"'else' command outside of conditional block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"break", 0, 0, 0 ) )
|
||||
{
|
||||
err( L"'break' command outside of loop block context undetected" );
|
||||
err( L"'break' command outside of loop block context undetected" );
|
||||
}
|
||||
if( !parser_test( L"exec ls|less", 0, 0, 0 ) || !parser_test( L"echo|return", 0, 0, 0 ))
|
||||
{
|
||||
err( L"Invalid pipe command undetected" );
|
||||
}
|
||||
err( L"Invalid pipe command undetected" );
|
||||
}
|
||||
|
||||
say( L"Testing basic evaluation" );
|
||||
if( !eval( 0, 0, TOP ) )
|
||||
{
|
||||
err( L"Null input when evaluating undetected" );
|
||||
}
|
||||
}
|
||||
if( !eval( L"ls", 0, WHILE ) )
|
||||
{
|
||||
err( L"Invalid block mode when evaluating undetected" );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Perform parameter expansion and test if the output equals the zero-terminated parameter list supplied.
|
||||
|
||||
|
@ -688,42 +688,42 @@ static void test_parser()
|
|||
|
||||
static int expand_test( const wchar_t *in, int flags, ... )
|
||||
{
|
||||
array_list_t out;
|
||||
array_list_t out;
|
||||
va_list va;
|
||||
int i=0;
|
||||
int res=1;
|
||||
wchar_t *arg;
|
||||
|
||||
|
||||
al_init( &out );
|
||||
if( expand_string( 0, wcsdup(in), &out, flags) )
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
va_start( va, flags );
|
||||
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
{
|
||||
if( al_get_count( &out ) == i )
|
||||
{
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
|
||||
if( wcscmp( al_get( &out, i ),arg) != 0 )
|
||||
|
||||
if( wcscmp( (wchar_t *)al_get( &out, i ),arg) != 0 )
|
||||
{
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
i++;
|
||||
}
|
||||
va_end( va );
|
||||
|
||||
|
||||
al_foreach( &out, &free );
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -732,7 +732,7 @@ static int expand_test( const wchar_t *in, int flags, ... )
|
|||
static void test_expand()
|
||||
{
|
||||
say( L"Testing parameter expansion" );
|
||||
|
||||
|
||||
if( !expand_test( L"foo", 0, L"foo", 0 ))
|
||||
{
|
||||
err( L"Strings do not expand to themselves" );
|
||||
|
@ -747,7 +747,7 @@ static void test_expand()
|
|||
{
|
||||
err( L"Cannot skip wildcard expansion" );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -758,17 +758,17 @@ static void test_path()
|
|||
say( L"Testing path functions" );
|
||||
|
||||
void *context = halloc( 0, 0 );
|
||||
|
||||
|
||||
|
||||
wchar_t *can = path_make_canonical( context, L"//foo//////bar/" );
|
||||
|
||||
|
||||
if( wcscmp( can, L"/foo/bar" ) )
|
||||
{
|
||||
err( L"Bug in canonical PATH code" );
|
||||
}
|
||||
|
||||
|
||||
halloc_free( context );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -785,72 +785,72 @@ void perf_complete()
|
|||
double t;
|
||||
wchar_t str[3]=
|
||||
{
|
||||
0, 0, 0
|
||||
0, 0, 0
|
||||
}
|
||||
;
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
|
||||
say( L"Testing completion performance" );
|
||||
al_init( &out );
|
||||
|
||||
|
||||
reader_push(L"");
|
||||
say( L"Here we go" );
|
||||
|
||||
|
||||
t1 = get_time();
|
||||
|
||||
|
||||
|
||||
|
||||
for( c=L'a'; c<=L'z'; c++ )
|
||||
{
|
||||
str[0]=c;
|
||||
reader_set_buffer( str, 0 );
|
||||
|
||||
|
||||
complete( str, &out );
|
||||
|
||||
|
||||
matches += al_get_count( &out );
|
||||
|
||||
|
||||
al_foreach( &out, &free );
|
||||
al_truncate( &out, 0 );
|
||||
}
|
||||
t2=get_time();
|
||||
|
||||
|
||||
t = (double)(t2-t1)/(1000000*26);
|
||||
|
||||
|
||||
say( L"One letter command completion took %f seconds per completion, %f microseconds/match", t, (double)(t2-t1)/matches );
|
||||
|
||||
|
||||
matches=0;
|
||||
t1 = get_time();
|
||||
for( i=0; i<LAPS; i++ )
|
||||
{
|
||||
str[0]='a'+(rand()%26);
|
||||
str[1]='a'+(rand()%26);
|
||||
|
||||
|
||||
reader_set_buffer( str, 0 );
|
||||
|
||||
|
||||
complete( str, &out );
|
||||
|
||||
|
||||
matches += al_get_count( &out );
|
||||
|
||||
|
||||
al_foreach( &out, &free );
|
||||
al_truncate( &out, 0 );
|
||||
}
|
||||
t2=get_time();
|
||||
|
||||
|
||||
t = (double)(t2-t1)/(1000000*LAPS);
|
||||
|
||||
|
||||
say( L"Two letter command completion took %f seconds per completion, %f microseconds/match", t, (double)(t2-t1)/matches );
|
||||
|
||||
|
||||
al_destroy( &out );
|
||||
|
||||
reader_pop();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Main test
|
||||
Main test
|
||||
*/
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
@ -858,13 +858,13 @@ int main( int argc, char **argv )
|
|||
srand( time( 0 ) );
|
||||
|
||||
program_name=L"(ignore)";
|
||||
|
||||
|
||||
say( L"Testing low-level functionality");
|
||||
say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." );
|
||||
|
||||
proc_init();
|
||||
proc_init();
|
||||
halloc_util_init();
|
||||
event_init();
|
||||
event_init();
|
||||
parser_init();
|
||||
function_init();
|
||||
builtin_init();
|
||||
|
@ -878,7 +878,7 @@ int main( int argc, char **argv )
|
|||
test_parser();
|
||||
test_expand();
|
||||
test_path();
|
||||
|
||||
|
||||
say( L"Encountered %d errors in low-level tests", err_count );
|
||||
|
||||
/*
|
||||
|
@ -886,9 +886,9 @@ int main( int argc, char **argv )
|
|||
*/
|
||||
// say( L"Testing performance" );
|
||||
// perf_complete();
|
||||
|
||||
|
||||
env_destroy();
|
||||
reader_destroy();
|
||||
reader_destroy();
|
||||
parser_destroy();
|
||||
function_destroy();
|
||||
builtin_destroy();
|
||||
|
@ -896,5 +896,5 @@ int main( int argc, char **argv )
|
|||
event_destroy();
|
||||
proc_destroy();
|
||||
halloc_util_destroy();
|
||||
|
||||
|
||||
}
|
||||
|
|
196
fishd.cpp
196
fishd.cpp
|
@ -78,7 +78,7 @@ time the original barrier request was sent have been received.
|
|||
/**
|
||||
Maximum length of socket filename
|
||||
*/
|
||||
#ifndef UNIX_PATH_MAX
|
||||
#ifndef UNIX_PATH_MAX
|
||||
#define UNIX_PATH_MAX 100
|
||||
#endif
|
||||
|
||||
|
@ -162,7 +162,7 @@ static char *get_socket_filename()
|
|||
uname = strdup( pw->pw_name );
|
||||
}
|
||||
|
||||
name = malloc( strlen(dir)+ strlen(uname)+ strlen(SOCK_FILENAME) + 2 );
|
||||
name = (char *)malloc( strlen(dir)+ strlen(uname)+ strlen(SOCK_FILENAME) + 2 );
|
||||
if( name == NULL )
|
||||
{
|
||||
wperror( L"get_socket_filename" );
|
||||
|
@ -182,7 +182,7 @@ static char *get_socket_filename()
|
|||
}
|
||||
|
||||
/**
|
||||
Signal handler for the term signal.
|
||||
Signal handler for the term signal.
|
||||
*/
|
||||
static void handle_term( int signal )
|
||||
{
|
||||
|
@ -192,17 +192,17 @@ static void handle_term( int signal )
|
|||
|
||||
/**
|
||||
Acquire the lock for the socket
|
||||
Returns the name of the lock file if successful or
|
||||
Returns the name of the lock file if successful or
|
||||
NULL if unable to obtain lock.
|
||||
The returned string must be free()d after unlink()ing the file to release
|
||||
The returned string must be free()d after unlink()ing the file to release
|
||||
the lock
|
||||
*/
|
||||
static char *acquire_socket_lock( const char *sock_name )
|
||||
{
|
||||
int len = strlen( sock_name );
|
||||
char *lockfile = malloc( len + strlen( LOCKPOSTFIX ) + 1 );
|
||||
|
||||
if( lockfile == NULL )
|
||||
char *lockfile = (char *)malloc( len + strlen( LOCKPOSTFIX ) + 1 );
|
||||
|
||||
if( lockfile == NULL )
|
||||
{
|
||||
wperror( L"acquire_socket_lock" );
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -237,13 +237,13 @@ static int get_socket()
|
|||
exit( EXIT_FAILURE );
|
||||
}
|
||||
debug( 4, L"Acquired lockfile: %s", lockfile );
|
||||
|
||||
|
||||
local.sun_family = AF_UNIX;
|
||||
strcpy( local.sun_path, sock_name );
|
||||
len = sizeof(local);
|
||||
|
||||
|
||||
debug(1, L"Connect to socket at %s", sock_name);
|
||||
|
||||
|
||||
if( ( s = socket( AF_UNIX, SOCK_STREAM, 0 ) ) == -1 )
|
||||
{
|
||||
wperror( L"socket" );
|
||||
|
@ -262,7 +262,7 @@ static int get_socket()
|
|||
exitcode = 0;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
||||
unlink( local.sun_path );
|
||||
if( bind( s, (struct sockaddr *)&local, len ) == -1 )
|
||||
{
|
||||
|
@ -288,9 +288,9 @@ unlock:
|
|||
/*
|
||||
End critical section protected by lock
|
||||
*/
|
||||
|
||||
|
||||
free( lockfile );
|
||||
|
||||
|
||||
free( sock_name );
|
||||
|
||||
if( doexit )
|
||||
|
@ -311,24 +311,24 @@ static void broadcast( int type, const wchar_t *key, const wchar_t *val )
|
|||
|
||||
if( !conn )
|
||||
return;
|
||||
|
||||
|
||||
msg = create_message( type, key, val );
|
||||
|
||||
|
||||
/*
|
||||
Don't merge these loops, or try_send_all can free the message
|
||||
prematurely
|
||||
*/
|
||||
|
||||
|
||||
for( c = conn; c; c=c->next )
|
||||
{
|
||||
msg->count++;
|
||||
q_put( &c->unsent, msg );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( c = conn; c; c=c->next )
|
||||
{
|
||||
try_send_all( c );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,7 +345,7 @@ static void daemonize()
|
|||
debug( 0, L"Could not put fishd in background. Quitting" );
|
||||
wperror( L"fork" );
|
||||
exit(1);
|
||||
|
||||
|
||||
case 0:
|
||||
{
|
||||
/*
|
||||
|
@ -366,19 +366,19 @@ static void daemonize()
|
|||
sigaction( SIGTERM, &act, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
{
|
||||
debug( 0, L"Parent process exiting (This is normal)" );
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Put ourself in out own processing group
|
||||
*/
|
||||
setsid();
|
||||
|
||||
|
||||
/*
|
||||
Close stdin and stdout. We only use stderr, anyway.
|
||||
*/
|
||||
|
@ -394,7 +394,7 @@ static wchar_t *fishd_env_get( wchar_t *key )
|
|||
{
|
||||
char *nres, *nkey;
|
||||
wchar_t *res;
|
||||
|
||||
|
||||
nkey = wcs2str( key );
|
||||
nres = getenv( nkey );
|
||||
free( nkey );
|
||||
|
@ -407,7 +407,7 @@ static wchar_t *fishd_env_get( wchar_t *key )
|
|||
res = env_universal_common_get( key );
|
||||
if( res )
|
||||
res = wcsdup( res );
|
||||
|
||||
|
||||
return env_universal_common_get( key );
|
||||
}
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ static wchar_t *fishd_get_config()
|
|||
wchar_t *xdg_dir, *home;
|
||||
int done = 0;
|
||||
wchar_t *res = 0;
|
||||
|
||||
|
||||
xdg_dir = fishd_env_get( L"XDG_CONFIG_HOME" );
|
||||
if( xdg_dir )
|
||||
{
|
||||
|
@ -439,7 +439,7 @@ static wchar_t *fishd_get_config()
|
|||
free( xdg_dir );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
home = fishd_env_get( L"HOME" );
|
||||
if( home )
|
||||
{
|
||||
|
@ -455,7 +455,7 @@ static wchar_t *fishd_get_config()
|
|||
free( home );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( done )
|
||||
{
|
||||
return res;
|
||||
|
@ -465,7 +465,7 @@ static wchar_t *fishd_get_config()
|
|||
debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -475,23 +475,23 @@ static void load_or_save( int save)
|
|||
{
|
||||
char *name;
|
||||
wchar_t *wdir = fishd_get_config();
|
||||
char *dir;
|
||||
char *dir;
|
||||
char hostname[HOSTNAME_LEN];
|
||||
connection_t c;
|
||||
int fd;
|
||||
|
||||
|
||||
if( !wdir )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dir = wcs2str( wdir );
|
||||
|
||||
free( wdir );
|
||||
|
||||
|
||||
gethostname( hostname, HOSTNAME_LEN );
|
||||
|
||||
name = malloc( strlen(dir)+ strlen(FILE)+ strlen(hostname) + 2 );
|
||||
|
||||
name = (char *)malloc( strlen(dir)+ strlen(FILE)+ strlen(hostname) + 2 );
|
||||
strcpy( name, dir );
|
||||
strcat( name, "/" );
|
||||
strcat( name, FILE );
|
||||
|
@ -499,20 +499,20 @@ static void load_or_save( int save)
|
|||
|
||||
free( dir );
|
||||
|
||||
|
||||
debug( 4, L"Open file for %s: '%s'",
|
||||
save?"saving":"loading",
|
||||
|
||||
debug( 4, L"Open file for %s: '%s'",
|
||||
save?"saving":"loading",
|
||||
name );
|
||||
|
||||
|
||||
fd = open( name, save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600);
|
||||
|
||||
|
||||
free( name );
|
||||
|
||||
|
||||
if( fd == -1 )
|
||||
{
|
||||
debug( 1, L"Could not open load/save file. No previous saves?" );
|
||||
wperror( L"open" );
|
||||
return;
|
||||
return;
|
||||
}
|
||||
debug( 4, L"File open on fd %d", c.fd );
|
||||
|
||||
|
@ -520,14 +520,14 @@ static void load_or_save( int save)
|
|||
|
||||
if( save )
|
||||
{
|
||||
|
||||
|
||||
write_loop( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
||||
enqueue_all( &c );
|
||||
}
|
||||
else
|
||||
read_message( &c );
|
||||
|
||||
connection_destroy( &c );
|
||||
connection_destroy( &c );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -553,10 +553,10 @@ static void init()
|
|||
{
|
||||
|
||||
sock = get_socket();
|
||||
daemonize();
|
||||
daemonize();
|
||||
env_universal_common_init( &broadcast );
|
||||
|
||||
load();
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -569,13 +569,13 @@ int main( int argc, char ** argv )
|
|||
socklen_t t;
|
||||
int max_fd;
|
||||
int update_count=0;
|
||||
|
||||
|
||||
fd_set read_fd, write_fd;
|
||||
|
||||
halloc_util_init();
|
||||
|
||||
|
||||
program_name=L"fishd";
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
|
||||
/*
|
||||
Parse options
|
||||
|
@ -586,57 +586,57 @@ int main( int argc, char ** argv )
|
|||
long_options[] =
|
||||
{
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
exit( 0 );
|
||||
|
||||
case '?':
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
while(1)
|
||||
while(1)
|
||||
{
|
||||
connection_t *c;
|
||||
int res;
|
||||
|
||||
t = sizeof( remote );
|
||||
|
||||
t = sizeof( remote );
|
||||
|
||||
FD_ZERO( &read_fd );
|
||||
FD_ZERO( &write_fd );
|
||||
FD_SET( sock, &read_fd );
|
||||
|
@ -645,7 +645,7 @@ int main( int argc, char ** argv )
|
|||
{
|
||||
FD_SET( c->fd, &read_fd );
|
||||
max_fd = maxi( max_fd, c->fd+1);
|
||||
|
||||
|
||||
if( ! q_empty( &c->unsent ) )
|
||||
{
|
||||
FD_SET( c->fd, &write_fd );
|
||||
|
@ -661,22 +661,22 @@ int main( int argc, char ** argv )
|
|||
save();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
if( res != -1 )
|
||||
break;
|
||||
|
||||
|
||||
if( errno != EINTR )
|
||||
{
|
||||
wperror( L"select" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( FD_ISSET( sock, &read_fd ) )
|
||||
{
|
||||
if( (child_socket =
|
||||
accept( sock,
|
||||
(struct sockaddr *)&remote,
|
||||
if( (child_socket =
|
||||
accept( sock,
|
||||
(struct sockaddr *)&remote,
|
||||
&t) ) == -1) {
|
||||
wperror( L"accept" );
|
||||
exit(1);
|
||||
|
@ -688,20 +688,20 @@ int main( int argc, char ** argv )
|
|||
if( fcntl( child_socket, F_SETFL, O_NONBLOCK ) != 0 )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
close( child_socket );
|
||||
close( child_socket );
|
||||
}
|
||||
else
|
||||
{
|
||||
connection_t *new = malloc( sizeof(connection_t));
|
||||
connection_init( new, child_socket );
|
||||
new->next = conn;
|
||||
send( new->fd, GREETING, strlen(GREETING), MSG_DONTWAIT );
|
||||
enqueue_all( new );
|
||||
conn=new;
|
||||
connection_t *newc = (connection_t *)malloc( sizeof(connection_t));
|
||||
connection_init( newc, child_socket );
|
||||
newc->next = conn;
|
||||
send( newc->fd, GREETING, strlen(GREETING), MSG_DONTWAIT );
|
||||
enqueue_all( newc );
|
||||
conn=newc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( c=conn; c; c=c->next )
|
||||
{
|
||||
if( FD_ISSET( c->fd, &write_fd ) )
|
||||
|
@ -709,7 +709,7 @@ int main( int argc, char ** argv )
|
|||
try_send_all( c );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( c=conn; c; c=c->next )
|
||||
{
|
||||
if( FD_ISSET( c->fd, &read_fd ) )
|
||||
|
@ -728,10 +728,10 @@ int main( int argc, char ** argv )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
connection_t *prev=0;
|
||||
c=conn;
|
||||
|
||||
|
||||
while( c )
|
||||
{
|
||||
if( c->killme )
|
||||
|
@ -745,7 +745,7 @@ int main( int argc, char ** argv )
|
|||
if( !msg->count )
|
||||
free( msg );
|
||||
}
|
||||
|
||||
|
||||
connection_destroy( c );
|
||||
if( prev )
|
||||
{
|
||||
|
@ -755,11 +755,11 @@ int main( int argc, char ** argv )
|
|||
{
|
||||
conn=c->next;
|
||||
}
|
||||
|
||||
|
||||
free(c);
|
||||
|
||||
|
||||
c=(prev?prev->next:conn);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -771,10 +771,10 @@ int main( int argc, char ** argv )
|
|||
if( !conn )
|
||||
{
|
||||
debug( 0, L"No more clients. Quitting" );
|
||||
save();
|
||||
save();
|
||||
env_universal_common_destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
halloc_util_destroy();
|
||||
|
|
409
function.cpp
409
function.cpp
|
@ -11,10 +11,13 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "wutil.h"
|
||||
#include "fallback.h"
|
||||
|
@ -43,7 +46,7 @@ typedef struct
|
|||
/** Function definition */
|
||||
wchar_t *definition;
|
||||
/** Function description */
|
||||
wchar_t *description;
|
||||
wchar_t *description;
|
||||
/**
|
||||
File where this function was defined
|
||||
*/
|
||||
|
@ -51,14 +54,14 @@ typedef struct
|
|||
/**
|
||||
Line where definition started
|
||||
*/
|
||||
int definition_offset;
|
||||
|
||||
int definition_offset;
|
||||
|
||||
/**
|
||||
List of all named arguments for this function
|
||||
*/
|
||||
array_list_t *named_arguments;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Flag for specifying that this function was automatically loaded
|
||||
*/
|
||||
|
@ -75,7 +78,37 @@ typedef struct
|
|||
/**
|
||||
Table containing all functions
|
||||
*/
|
||||
static hash_table_t function;
|
||||
static hash_table_t functions;
|
||||
|
||||
/* Lock for functions */
|
||||
static pthread_mutex_t functions_lock;
|
||||
|
||||
/* Helper macro for vomiting */
|
||||
#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0)
|
||||
|
||||
static int kLockDepth = 0;
|
||||
static char kLockFunction[1024];
|
||||
|
||||
/**
|
||||
Lock and unlock the functions hash
|
||||
*/
|
||||
static void lock_functions(const char *func) {
|
||||
VOMIT_ON_FAILURE(pthread_mutex_lock(&functions_lock));
|
||||
if (! kLockDepth++) {
|
||||
strcat(kLockFunction, func);
|
||||
}
|
||||
}
|
||||
|
||||
static void unlock_functions(void) {
|
||||
if (! --kLockDepth) {
|
||||
memset(kLockFunction, 0, sizeof kLockFunction);
|
||||
}
|
||||
VOMIT_ON_FAILURE(pthread_mutex_unlock(&functions_lock));
|
||||
}
|
||||
|
||||
#define LOCK_FUNCTIONS() lock_functions(__FUNCTION__)
|
||||
#define UNLOCK_FUNCTIONS() unlock_functions()
|
||||
|
||||
|
||||
/**
|
||||
Kludgy flag set by the load function in order to tell function_add
|
||||
|
@ -93,11 +126,15 @@ static int load( const wchar_t *name )
|
|||
int was_autoload = is_autoload;
|
||||
int res;
|
||||
function_internal_data_t *data;
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data && !data->is_autoload )
|
||||
LOCK_FUNCTIONS();
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
if( data && !data->is_autoload ) {
|
||||
UNLOCK_FUNCTIONS();
|
||||
return 0;
|
||||
|
||||
is_autoload = 1;
|
||||
}
|
||||
UNLOCK_FUNCTIONS();
|
||||
|
||||
is_autoload = 1;
|
||||
res = parse_util_load( name,
|
||||
L"fish_function_path",
|
||||
&function_remove,
|
||||
|
@ -113,13 +150,13 @@ static int load( const wchar_t *name )
|
|||
static void autoload_names( array_list_t *out, int get_hidden )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
array_list_t path_list;
|
||||
const wchar_t *path_var = env_get( L"fish_function_path" );
|
||||
|
||||
|
||||
if( ! path_var )
|
||||
return;
|
||||
|
||||
|
||||
al_init( &path_list );
|
||||
|
||||
tokenize_variable_array( path_var, &path_list );
|
||||
|
@ -129,15 +166,15 @@ static void autoload_names( array_list_t *out, int get_hidden )
|
|||
DIR *dir = wopendir( ndir );
|
||||
if( !dir )
|
||||
continue;
|
||||
|
||||
struct wdirent *next;
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
|
||||
wcstring name;
|
||||
while (wreaddir(dir, name))
|
||||
{
|
||||
wchar_t *fn = next->d_name;
|
||||
const wchar_t *fn = name.c_str();
|
||||
wchar_t *suffix;
|
||||
if( !get_hidden && fn[0] == L'_' )
|
||||
continue;
|
||||
|
||||
|
||||
suffix = wcsrchr( fn, L'.' );
|
||||
if( suffix && (wcscmp( suffix, L".fish" ) == 0 ) )
|
||||
{
|
||||
|
@ -148,7 +185,7 @@ static void autoload_names( array_list_t *out, int get_hidden )
|
|||
DIE_MEM();
|
||||
al_push( out, dup );
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
al_foreach( &path_list, &free );
|
||||
|
@ -157,9 +194,15 @@ static void autoload_names( array_list_t *out, int get_hidden )
|
|||
|
||||
void function_init()
|
||||
{
|
||||
hash_init( &function,
|
||||
hash_init( &functions,
|
||||
&hash_wcs_func,
|
||||
&hash_wcs_cmp );
|
||||
|
||||
pthread_mutexattr_t a;
|
||||
VOMIT_ON_FAILURE(pthread_mutexattr_init(&a));
|
||||
VOMIT_ON_FAILURE(pthread_mutexattr_settype(&a,PTHREAD_MUTEX_RECURSIVE));
|
||||
VOMIT_ON_FAILURE(pthread_mutex_init(&functions_lock, &a));
|
||||
VOMIT_ON_FAILURE(pthread_mutexattr_destroy(&a));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,8 +215,10 @@ static void clear_entry( void *key, void *value )
|
|||
|
||||
void function_destroy()
|
||||
{
|
||||
hash_foreach( &function, &clear_entry );
|
||||
hash_destroy( &function );
|
||||
LOCK_FUNCTIONS();
|
||||
hash_foreach( &functions, &clear_entry );
|
||||
hash_destroy( &functions );
|
||||
UNLOCK_FUNCTIONS();
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,13 +227,13 @@ void function_add( function_data_t *data )
|
|||
int i;
|
||||
wchar_t *cmd_end;
|
||||
function_internal_data_t *d;
|
||||
|
||||
|
||||
CHECK( data->name, );
|
||||
CHECK( data->definition, );
|
||||
|
||||
LOCK_FUNCTIONS();
|
||||
function_remove( data->name );
|
||||
|
||||
d = halloc( 0, sizeof( function_internal_data_t ) );
|
||||
|
||||
d = (function_internal_data_t *)halloc( 0, sizeof( function_internal_data_t ) );
|
||||
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
|
||||
d->definition = halloc_wcsdup( d, data->definition );
|
||||
|
||||
|
@ -201,21 +246,162 @@ void function_add( function_data_t *data )
|
|||
al_push( d->named_arguments, halloc_wcsdup( d, (wchar_t *)al_get( data->named_arguments, i ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cmd_end = d->definition + wcslen(d->definition)-1;
|
||||
|
||||
|
||||
d->description = data->description?halloc_wcsdup( d, data->description ):0;
|
||||
d->definition_file = intern(reader_current_filename());
|
||||
d->is_autoload = is_autoload;
|
||||
d->shadows = data->shadows;
|
||||
|
||||
hash_put( &function, intern(data->name), d );
|
||||
|
||||
|
||||
hash_put( &functions, intern(data->name), d );
|
||||
|
||||
for( i=0; i<al_get_count( data->events ); i++ )
|
||||
{
|
||||
event_add_handler( (event_t *)al_get( data->events, i ) );
|
||||
}
|
||||
UNLOCK_FUNCTIONS();
|
||||
}
|
||||
|
||||
static int function_exists_internal( const wchar_t *cmd, int autoload )
|
||||
{
|
||||
int res;
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
if( parser_keywords_is_reserved(cmd) )
|
||||
return 0;
|
||||
|
||||
LOCK_FUNCTIONS();
|
||||
if ( autoload ) load( cmd );
|
||||
res = (hash_get(&functions, cmd) != 0 );
|
||||
UNLOCK_FUNCTIONS();
|
||||
return res;
|
||||
}
|
||||
|
||||
int function_exists( const wchar_t *cmd )
|
||||
{
|
||||
return function_exists_internal( cmd, 1 );
|
||||
}
|
||||
|
||||
int function_exists_no_autoload( const wchar_t *cmd )
|
||||
{
|
||||
return function_exists_internal( cmd, 0 );
|
||||
}
|
||||
|
||||
void function_remove( const wchar_t *name )
|
||||
{
|
||||
void *key;
|
||||
void *dv;
|
||||
function_internal_data_t *d;
|
||||
event_t ev;
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
LOCK_FUNCTIONS();
|
||||
hash_remove( &functions,
|
||||
name,
|
||||
&key,
|
||||
&dv );
|
||||
|
||||
d=(function_internal_data_t *)dv;
|
||||
|
||||
if( !key ) {
|
||||
UNLOCK_FUNCTIONS();
|
||||
return;
|
||||
}
|
||||
|
||||
ev.type=EVENT_ANY;
|
||||
ev.function_name=name;
|
||||
event_remove( &ev );
|
||||
|
||||
halloc_free( d );
|
||||
|
||||
/*
|
||||
Notify the autoloader that the specified function is erased, but
|
||||
only if this call to fish_remove is not made by the autoloader
|
||||
itself.
|
||||
*/
|
||||
if( !is_autoload )
|
||||
{
|
||||
parse_util_unload( name, L"fish_function_path", 0 );
|
||||
}
|
||||
UNLOCK_FUNCTIONS();
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
LOCK_FUNCTIONS();
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->definition;
|
||||
}
|
||||
|
||||
array_list_t *function_get_named_arguments( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
LOCK_FUNCTIONS();
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->named_arguments;
|
||||
}
|
||||
|
||||
int function_get_shadows( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
LOCK_FUNCTIONS();
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->shadows;
|
||||
}
|
||||
|
||||
|
||||
const wchar_t *function_get_desc( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
load( name );
|
||||
LOCK_FUNCTIONS();
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
return _(data->description);
|
||||
}
|
||||
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, );
|
||||
CHECK( desc, );
|
||||
|
||||
load( name );
|
||||
LOCK_FUNCTIONS();
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return;
|
||||
|
||||
data->description = halloc_wcsdup( data, desc );
|
||||
}
|
||||
|
||||
int function_copy( const wchar_t *name, const wchar_t *new_name )
|
||||
|
@ -226,11 +412,11 @@ int function_copy( const wchar_t *name, const wchar_t *new_name )
|
|||
CHECK( name, 0 );
|
||||
CHECK( new_name, 0 );
|
||||
|
||||
orig_d = (function_internal_data_t *)hash_get(&function, name);
|
||||
orig_d = (function_internal_data_t *)hash_get(&functions, name);
|
||||
if( !orig_d )
|
||||
return 0;
|
||||
|
||||
d = halloc(0, sizeof( function_internal_data_t ) );
|
||||
d = (function_internal_data_t *)halloc(0, sizeof( function_internal_data_t ) );
|
||||
d->definition_offset = orig_d->definition_offset;
|
||||
d->definition = halloc_wcsdup( d, orig_d->definition );
|
||||
if( orig_d->named_arguments )
|
||||
|
@ -249,129 +435,11 @@ int function_copy( const wchar_t *name, const wchar_t *new_name )
|
|||
d->is_autoload = 0;
|
||||
}
|
||||
|
||||
hash_put( &function, intern(new_name), d );
|
||||
hash_put( &functions, intern(new_name), d );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int function_exists( const wchar_t *cmd )
|
||||
{
|
||||
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
if( parser_keywords_is_reserved(cmd) )
|
||||
return 0;
|
||||
|
||||
load( cmd );
|
||||
return (hash_get(&function, cmd) != 0 );
|
||||
}
|
||||
|
||||
void function_remove( const wchar_t *name )
|
||||
{
|
||||
void *key;
|
||||
void *dv;
|
||||
function_internal_data_t *d;
|
||||
event_t ev;
|
||||
|
||||
CHECK( name, );
|
||||
|
||||
hash_remove( &function,
|
||||
name,
|
||||
&key,
|
||||
&dv );
|
||||
|
||||
d=(function_internal_data_t *)dv;
|
||||
|
||||
if( !key )
|
||||
return;
|
||||
|
||||
ev.type=EVENT_ANY;
|
||||
ev.function_name=name;
|
||||
event_remove( &ev );
|
||||
|
||||
halloc_free( d );
|
||||
|
||||
/*
|
||||
Notify the autoloader that the specified function is erased, but
|
||||
only if this call to fish_remove is not made by the autoloader
|
||||
itself.
|
||||
*/
|
||||
if( !is_autoload )
|
||||
{
|
||||
parse_util_unload( name, L"fish_function_path", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->definition;
|
||||
}
|
||||
|
||||
array_list_t *function_get_named_arguments( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->named_arguments;
|
||||
}
|
||||
|
||||
int function_get_shadows( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->shadows;
|
||||
}
|
||||
|
||||
|
||||
const wchar_t *function_get_desc( const wchar_t *name )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
return _(data->description);
|
||||
}
|
||||
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
{
|
||||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, );
|
||||
CHECK( desc, );
|
||||
|
||||
load( name );
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return;
|
||||
|
||||
data->description = halloc_wcsdup( data, desc );
|
||||
}
|
||||
|
||||
/**
|
||||
Search arraylist of strings for specified string
|
||||
*/
|
||||
|
@ -381,19 +449,19 @@ static int al_contains_str( array_list_t *list, const wchar_t * str )
|
|||
|
||||
CHECK( list, 0 );
|
||||
CHECK( str, 0 );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( list ); i++ )
|
||||
{
|
||||
if( wcscmp( al_get( list, i ), str) == 0 )
|
||||
if( wcscmp( (const wchar_t *)al_get( list, i ), str) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
static void get_names_internal( void *key,
|
||||
void *val,
|
||||
|
@ -407,14 +475,14 @@ static void get_names_internal( void *key,
|
|||
}
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
static void get_names_internal_all( void *key,
|
||||
void *val,
|
||||
void *aux )
|
||||
{
|
||||
wchar_t *name = (wchar_t *)key;
|
||||
|
||||
|
||||
if( !al_contains_str( (array_list_t *)aux, name ) )
|
||||
{
|
||||
al_push( (array_list_t *)aux, name );
|
||||
|
@ -424,18 +492,19 @@ static void get_names_internal_all( void *key,
|
|||
void function_get_names( array_list_t *list, int get_hidden )
|
||||
{
|
||||
CHECK( list, );
|
||||
|
||||
LOCK_FUNCTIONS();
|
||||
autoload_names( list, get_hidden );
|
||||
|
||||
|
||||
if( get_hidden )
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal_all, list );
|
||||
hash_foreach2( &functions, &get_names_internal_all, list );
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal, list );
|
||||
hash_foreach2( &functions, &get_names_internal, list );
|
||||
}
|
||||
|
||||
UNLOCK_FUNCTIONS();
|
||||
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition_file( const wchar_t *name )
|
||||
|
@ -443,11 +512,12 @@ const wchar_t *function_get_definition_file( const wchar_t *name )
|
|||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, 0 );
|
||||
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
LOCK_FUNCTIONS();
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
return data->definition_file;
|
||||
}
|
||||
|
||||
|
@ -457,11 +527,12 @@ int function_get_definition_offset( const wchar_t *name )
|
|||
function_internal_data_t *data;
|
||||
|
||||
CHECK( name, -1 );
|
||||
|
||||
data = (function_internal_data_t *)hash_get( &function, name );
|
||||
LOCK_FUNCTIONS();
|
||||
data = (function_internal_data_t *)hash_get( &functions, name );
|
||||
UNLOCK_FUNCTIONS();
|
||||
if( data == 0 )
|
||||
return -1;
|
||||
|
||||
|
||||
return data->definition_offset;
|
||||
}
|
||||
|
||||
|
|
24
function.h
24
function.h
|
@ -1,4 +1,4 @@
|
|||
/** \file function.h
|
||||
/** \file function.h
|
||||
|
||||
Prototypes for functions for storing and retrieving function
|
||||
information. These functions also take care of autoloading
|
||||
|
@ -53,7 +53,7 @@ typedef struct function_data
|
|||
|
||||
|
||||
/**
|
||||
Initialize function data
|
||||
Initialize function data
|
||||
*/
|
||||
void function_init();
|
||||
|
||||
|
@ -93,14 +93,19 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc );
|
|||
*/
|
||||
int function_exists( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns true if the function with the name name exists, without triggering autoload.
|
||||
*/
|
||||
int function_exists_no_autoload( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Insert all function names into l. These are not copies of the
|
||||
strings and should not be freed after use.
|
||||
|
||||
|
||||
\param list the list to add the names to
|
||||
\param get_hidden whether to include hidden functions, i.e. ones starting with an underscore
|
||||
*/
|
||||
void function_get_names( array_list_t *list,
|
||||
void function_get_names( array_list_t *list,
|
||||
int get_hidden );
|
||||
|
||||
/**
|
||||
|
@ -126,15 +131,16 @@ int function_get_definition_offset( const wchar_t *name );
|
|||
*/
|
||||
array_list_t *function_get_named_arguments( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns whether this function shadows variables of the underlying function
|
||||
*/
|
||||
int function_get_shadows( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Creates a new function using the same definition as the specified function.
|
||||
Returns non-zero if copy is successful.
|
||||
*/
|
||||
int function_copy( const wchar_t *name, const wchar_t *new_name );
|
||||
|
||||
|
||||
/**
|
||||
Returns whether this function shadows variables of the underlying function
|
||||
*/
|
||||
int function_get_shadows( const wchar_t *name );
|
||||
|
||||
#endif
|
||||
|
|
46
halloc.cpp
46
halloc.cpp
|
@ -125,37 +125,37 @@ static void halloc_report()
|
|||
{
|
||||
if( getpid() == pid )
|
||||
{
|
||||
debug( 1, L"%d parents, %d children with average child size of %.2f bytes caused %d allocs, average spill of %.2f bytes",
|
||||
debug( 1, L"%d parents, %d children with average child size of %.2f bytes caused %d allocs, average spill of %.2f bytes",
|
||||
parent_count, child_count, (double)child_size/child_count,
|
||||
parent_count+alloc_count, (double)alloc_spill/(parent_count+alloc_count) );
|
||||
parent_count+alloc_count, (double)alloc_spill/(parent_count+alloc_count) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void *halloc( void *context, size_t size )
|
||||
{
|
||||
{
|
||||
halloc_t *me, *parent;
|
||||
if( context )
|
||||
{
|
||||
char *res;
|
||||
char *aligned;
|
||||
|
||||
|
||||
#ifdef HALLOC_DEBUG
|
||||
|
||||
|
||||
if( !child_count )
|
||||
{
|
||||
pid = getpid();
|
||||
atexit( &halloc_report );
|
||||
}
|
||||
|
||||
|
||||
child_count++;
|
||||
child_size += size;
|
||||
#endif
|
||||
#endif
|
||||
parent = halloc_from_data( context );
|
||||
|
||||
/*
|
||||
Align memory address
|
||||
Align memory address
|
||||
*/
|
||||
aligned = align_ptr( parent->scratch );
|
||||
|
||||
|
@ -163,7 +163,7 @@ void *halloc( void *context, size_t size )
|
|||
|
||||
if( parent->scratch_free < 0 )
|
||||
parent->scratch_free=0;
|
||||
|
||||
|
||||
parent->scratch = aligned;
|
||||
|
||||
if( size <= parent->scratch_free )
|
||||
|
@ -177,14 +177,14 @@ void *halloc( void *context, size_t size )
|
|||
|
||||
#ifdef HALLOC_DEBUG
|
||||
alloc_count++;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if( parent->scratch_free < HALLOC_SCRAP_SIZE )
|
||||
{
|
||||
#ifdef HALLOC_DEBUG
|
||||
alloc_spill += parent->scratch_free;
|
||||
#endif
|
||||
res = calloc( 1, size + HALLOC_BLOCK_SIZE );
|
||||
res = (char *)calloc( 1, size + HALLOC_BLOCK_SIZE );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
parent->scratch = (char *)res + size;
|
||||
|
@ -192,29 +192,29 @@ void *halloc( void *context, size_t size )
|
|||
}
|
||||
else
|
||||
{
|
||||
res = calloc( 1, size );
|
||||
res = (char *)calloc( 1, size );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
}
|
||||
al_push_func( &parent->children, &late_free );
|
||||
al_push_func( &parent->children, (void (*)())&late_free );
|
||||
al_push( &parent->children, res );
|
||||
|
||||
|
||||
}
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
me = (halloc_t *)calloc( 1, align_sz(sizeof(halloc_t)) + align_sz(size) + HALLOC_BLOCK_SIZE );
|
||||
|
||||
|
||||
if( !me )
|
||||
DIE_MEM();
|
||||
#ifdef HALLOC_DEBUG
|
||||
parent_count++;
|
||||
#endif
|
||||
#endif
|
||||
me->scratch = ((char *)me) + align_sz(sizeof(halloc_t)) + align_sz(size);
|
||||
me->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
|
||||
|
||||
al_init( &me->children );
|
||||
return ((char *)me) + align_sz(sizeof(halloc_t));
|
||||
}
|
||||
|
@ -225,9 +225,9 @@ void halloc_register_function( void *context, void (*func)(void *), void *data )
|
|||
halloc_t *me;
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
|
||||
me = halloc_from_data( context );
|
||||
al_push_func( &me->children, func );
|
||||
al_push_func( &me->children, (void (*)())func );
|
||||
al_push( &me->children, data );
|
||||
}
|
||||
|
||||
|
@ -235,11 +235,11 @@ void halloc_free( void *context )
|
|||
{
|
||||
halloc_t *me;
|
||||
int i;
|
||||
|
||||
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
me = halloc_from_data( context );
|
||||
|
||||
#ifdef HALLOC_DEBUG
|
||||
|
|
2
halloc.h
2
halloc.h
|
@ -1,4 +1,4 @@
|
|||
/** \file halloc.h
|
||||
/** \file halloc.h
|
||||
|
||||
A hierarchical memory allocation system. Works mostly like talloc
|
||||
used in Samba, except that an arbitrary block allocated with
|
||||
|
|
|
@ -33,7 +33,7 @@ void halloc_util_destroy()
|
|||
|
||||
array_list_t *al_halloc( void *context )
|
||||
{
|
||||
array_list_t *res = halloc( context, sizeof( array_list_t ) );
|
||||
array_list_t *res = (array_list_t *)halloc( context, sizeof( array_list_t ) );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
al_init( res );
|
||||
|
@ -43,7 +43,7 @@ array_list_t *al_halloc( void *context )
|
|||
|
||||
string_buffer_t *sb_halloc( void *context )
|
||||
{
|
||||
string_buffer_t *res = halloc( context, sizeof( string_buffer_t ) );
|
||||
string_buffer_t *res = (string_buffer_t *)halloc( context, sizeof( string_buffer_t ) );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
sb_init( res );
|
||||
|
@ -69,7 +69,7 @@ void *halloc_register( void *context, void *data )
|
|||
{
|
||||
if( !data )
|
||||
return 0;
|
||||
|
||||
|
||||
halloc_register_function( context, &free, data );
|
||||
return data;
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ void *halloc_register( void *context, void *data )
|
|||
wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
|
||||
|
||||
wchar_t *out = (wchar_t *)halloc( context, sizeof( wchar_t)*(len+1));
|
||||
|
||||
if( out == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
@ -89,12 +89,12 @@ wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
|
|||
|
||||
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c )
|
||||
{
|
||||
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
|
||||
wchar_t *res = (wchar_t *)halloc( context, sizeof(wchar_t)*(c+1) );
|
||||
if( res == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
wcslcpy( res, in, c+1 );
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
}
|
||||
|
|
651
highlight.cpp
651
highlight.cpp
File diff suppressed because it is too large
Load diff
13
highlight.h
13
highlight.h
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "env.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
|
@ -56,7 +57,7 @@
|
|||
/**
|
||||
Internal value representing highlighting of an IO redirection
|
||||
*/
|
||||
#define HIGHLIGHT_REDIRECTION 0x800
|
||||
#define HIGHLIGHT_REDIRECTION 0x800
|
||||
/**
|
||||
Internal value representing highlighting a potentially valid path
|
||||
*/
|
||||
|
@ -68,11 +69,11 @@
|
|||
for each character in buff.
|
||||
|
||||
\param buff The buffer on which to perform syntax highlighting
|
||||
\param color The array in wchich to store the color codes. The first 8 bits are used for fg color, the next 8 bits for bg color.
|
||||
\param color The array in wchich to store the color codes. The first 8 bits are used for fg color, the next 8 bits for bg color.
|
||||
\param pos the cursor position. Used for quote matching, etc.
|
||||
\param error a list in which a description of each error will be inserted. May be 0, in whcich case no error descriptions will be generated.
|
||||
*/
|
||||
void highlight_shell( wchar_t * buff, int *color, int pos, array_list_t *error );
|
||||
void highlight_shell( const wchar_t *, int *, int, array_list_t *, const env_vars &vars );
|
||||
|
||||
/**
|
||||
Perform syntax highlighting for the text in buff. Matching quotes and paranthesis are highlighted. The result is
|
||||
|
@ -80,17 +81,17 @@ void highlight_shell( wchar_t * buff, int *color, int pos, array_list_t *error )
|
|||
for each character in buff.
|
||||
|
||||
\param buff The buffer on which to perform syntax highlighting
|
||||
\param color The array in wchich to store the color codes. The first 8 bits are used for fg color, the next 8 bits for bg color.
|
||||
\param color The array in wchich to store the color codes. The first 8 bits are used for fg color, the next 8 bits for bg color.
|
||||
\param pos the cursor position. Used for quote matching, etc.
|
||||
\param error a list in which a description of each error will be inserted. May be 0, in whcich case no error descriptions will be generated.
|
||||
*/
|
||||
void highlight_universal( wchar_t * buff, int *color, int pos, array_list_t *error );
|
||||
void highlight_universal( const wchar_t *, int *, int, array_list_t *, const env_vars &vars );
|
||||
|
||||
/**
|
||||
Translate from HIGHLIGHT_* to FISH_COLOR_* according to environment
|
||||
variables. Defaults to FISH_COLOR_NORMAL.
|
||||
|
||||
Example:
|
||||
Example:
|
||||
|
||||
If the environment variable FISH_FISH_COLOR_ERROR is set to 'red', a
|
||||
call to highlight_get_color( HIGHLIGHT_ERROR) will return
|
||||
|
|
238
history.cpp
238
history.cpp
|
@ -43,13 +43,13 @@
|
|||
/**
|
||||
A struct representiong a history list
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
The name of this list. Used for picking a suitable filename and for switching modes.
|
||||
*/
|
||||
const wchar_t *name;
|
||||
|
||||
|
||||
/**
|
||||
The items of the list. Each entry may be either a pointer to an
|
||||
item_t struct or a pointer to an mmaped memory region where a
|
||||
|
@ -66,12 +66,12 @@ typedef struct
|
|||
this session.
|
||||
*/
|
||||
hash_table_t session_item;
|
||||
|
||||
|
||||
/**
|
||||
The current history position
|
||||
*/
|
||||
int pos;
|
||||
|
||||
|
||||
/**
|
||||
This flag is set nonzero if the file containing earlier saves has ben mmaped in
|
||||
*/
|
||||
|
@ -91,7 +91,7 @@ typedef struct
|
|||
A list of indices of all previous search maches. This is used to eliminate duplicate search results.
|
||||
*/
|
||||
array_list_t used;
|
||||
|
||||
|
||||
/**
|
||||
Timestamp of last save
|
||||
*/
|
||||
|
@ -114,13 +114,13 @@ typedef struct
|
|||
/**
|
||||
This struct represents a history item
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
The actual contents of the entry
|
||||
*/
|
||||
wchar_t *data;
|
||||
|
||||
|
||||
/**
|
||||
Original creation time for the entry
|
||||
*/
|
||||
|
@ -154,7 +154,7 @@ static int hash_item_cmp( void *v1, void *v2 )
|
|||
{
|
||||
item_t *i1 = (item_t *)v1;
|
||||
item_t *i2 = (item_t *)v2;
|
||||
return (i1->timestamp == i2->timestamp) && (wcscmp( i1->data, i2->data )==0);
|
||||
return (i1->timestamp == i2->timestamp) && (wcscmp( i1->data, i2->data )==0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +198,7 @@ static wchar_t *history_escape_newlines( wchar_t *in )
|
|||
*/
|
||||
sb_append_char( out, L'\n' );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if( *in == L'\n' )
|
||||
{
|
||||
|
@ -209,7 +209,7 @@ static wchar_t *history_escape_newlines( wchar_t *in )
|
|||
{
|
||||
sb_append_char( out, *in );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return (wchar_t *)out->buff;
|
||||
}
|
||||
|
@ -256,14 +256,14 @@ static wchar_t *history_unescape_newlines( wchar_t *in )
|
|||
Check if the specified item is already loaded
|
||||
*/
|
||||
static int item_is_new( history_mode_t *m, void *d )
|
||||
{
|
||||
{
|
||||
char *begin = (char *)d;
|
||||
|
||||
if( !m->has_loaded || !m->mmap_start || (m->mmap_start == MAP_FAILED ) )
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( (begin < m->mmap_start) || (begin > (m->mmap_start+m->mmap_length) ) )
|
||||
{
|
||||
return 1;
|
||||
|
@ -277,7 +277,7 @@ static int item_is_new( history_mode_t *m, void *d )
|
|||
Later calls to this function may erase the output of a previous call to this function.
|
||||
*/
|
||||
static item_t *item_get( history_mode_t *m, void *d )
|
||||
{
|
||||
{
|
||||
char *begin = (char *)d;
|
||||
|
||||
if( item_is_new( m, d ) )
|
||||
|
@ -286,18 +286,18 @@ static item_t *item_get( history_mode_t *m, void *d )
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
char *end = m->mmap_start + m->mmap_length;
|
||||
char *pos=begin;
|
||||
|
||||
int was_backslash = 0;
|
||||
|
||||
int was_backslash = 0;
|
||||
static string_buffer_t *out = 0;
|
||||
static item_t narrow_item;
|
||||
int first_char = 1;
|
||||
int first_char = 1;
|
||||
int timestamp_mode = 0;
|
||||
|
||||
narrow_item.timestamp = 0;
|
||||
|
||||
|
||||
if( !out )
|
||||
{
|
||||
out = sb_halloc( global_context );
|
||||
|
@ -310,17 +310,17 @@ static item_t *item_get( history_mode_t *m, void *d )
|
|||
{
|
||||
sb_clear( out );
|
||||
}
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
wchar_t c;
|
||||
mbstate_t state;
|
||||
size_t res;
|
||||
|
||||
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
|
||||
res = mbrtowc( &c, pos, end-pos, &state );
|
||||
|
||||
|
||||
if( res == (size_t)-1 )
|
||||
{
|
||||
pos++;
|
||||
|
@ -336,7 +336,7 @@ static item_t *item_get( history_mode_t *m, void *d )
|
|||
continue;
|
||||
}
|
||||
pos += res;
|
||||
|
||||
|
||||
if( c == L'\n' )
|
||||
{
|
||||
if( timestamp_mode )
|
||||
|
@ -345,21 +345,21 @@ static item_t *item_get( history_mode_t *m, void *d )
|
|||
while( *time_string && !iswdigit(*time_string))
|
||||
time_string++;
|
||||
errno=0;
|
||||
|
||||
|
||||
if( *time_string )
|
||||
{
|
||||
time_t tm;
|
||||
wchar_t *end;
|
||||
|
||||
|
||||
errno = 0;
|
||||
tm = (time_t)wcstol( time_string, &end, 10 );
|
||||
|
||||
|
||||
if( tm && !errno && !*end )
|
||||
{
|
||||
narrow_item.timestamp = tm;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sb_clear( out );
|
||||
timestamp_mode = 0;
|
||||
|
@ -368,21 +368,21 @@ static item_t *item_get( history_mode_t *m, void *d )
|
|||
if( !was_backslash )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( first_char )
|
||||
{
|
||||
if( c == L'#' )
|
||||
if( c == L'#' )
|
||||
timestamp_mode = 1;
|
||||
}
|
||||
|
||||
|
||||
first_char = 0;
|
||||
|
||||
|
||||
sb_append_char( out, c );
|
||||
|
||||
|
||||
was_backslash = ( (c == L'\\') && !was_backslash);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
narrow_item.data = history_unescape_newlines((wchar_t *)out->buff);
|
||||
return &narrow_item;
|
||||
}
|
||||
|
@ -404,12 +404,12 @@ static int item_write( FILE *f, history_mode_t *m, void *v )
|
|||
static void history_destroy_mode( history_mode_t *m )
|
||||
{
|
||||
halloc_free( m->item_context );
|
||||
|
||||
|
||||
if( m->mmap_start && (m->mmap_start != MAP_FAILED ))
|
||||
{
|
||||
munmap( m->mmap_start, m->mmap_length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,12 +421,12 @@ static void history_destroy_mode_wrapper( void *n, history_mode_t *m )
|
|||
}
|
||||
|
||||
/**
|
||||
Create a new empty mode with the specified name.
|
||||
Create a new empty mode with the specified name.
|
||||
The mode is a halloc context, and the entire mode can be destroyed using halloc_free().
|
||||
*/
|
||||
static history_mode_t *history_create_mode( const wchar_t *name )
|
||||
{
|
||||
history_mode_t *new_mode = halloc( 0, sizeof( history_mode_t ));
|
||||
{
|
||||
history_mode_t *new_mode = (history_mode_t *)halloc( 0, sizeof( history_mode_t ));
|
||||
|
||||
new_mode->name = intern(name);
|
||||
|
||||
|
@ -434,16 +434,16 @@ static history_mode_t *history_create_mode( const wchar_t *name )
|
|||
al_init( &new_mode->used );
|
||||
halloc_register_function( new_mode, (void (*)(void *))&al_destroy, &new_mode->item );
|
||||
halloc_register_function( new_mode, (void (*)(void *))&al_destroy, &new_mode->used );
|
||||
|
||||
|
||||
hash_init( &new_mode->session_item, &hash_item_func, &hash_item_cmp );
|
||||
halloc_register_function( new_mode, (void (*)(void *))&hash_destroy, &new_mode->session_item );
|
||||
|
||||
|
||||
new_mode->save_timestamp=time(0);
|
||||
new_mode->item_context = halloc( 0,0 );
|
||||
|
||||
halloc_register_function( new_mode, (void (*)(void *))&history_destroy_mode, new_mode );
|
||||
|
||||
return new_mode;
|
||||
return new_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -464,17 +464,17 @@ static int history_test( const wchar_t *needle, const wchar_t *haystack )
|
|||
static wchar_t *history_filename( void *context, const wchar_t *name, const wchar_t *suffix )
|
||||
{
|
||||
wchar_t *path;
|
||||
wchar_t *res;
|
||||
wchar_t *res;
|
||||
|
||||
if( !current_mode )
|
||||
return 0;
|
||||
|
||||
|
||||
path = path_get_config( context );
|
||||
|
||||
if( !path )
|
||||
return 0;
|
||||
|
||||
res = wcsdupcat( path, L"/", name, L"_history", suffix?suffix:(void *)0);
|
||||
|
||||
res = wcsdupcat( path, L"/", name, L"_history", suffix?suffix:NULL);
|
||||
halloc_register_function( context, &free, res );
|
||||
return res;
|
||||
}
|
||||
|
@ -483,24 +483,24 @@ static wchar_t *history_filename( void *context, const wchar_t *name, const wcha
|
|||
Go through the mmaped region and insert pointers to suitable loacations into the item list
|
||||
*/
|
||||
static void history_populate_from_mmap( history_mode_t *m )
|
||||
{
|
||||
{
|
||||
char *begin = m->mmap_start;
|
||||
char *end = begin + m->mmap_length;
|
||||
char *pos;
|
||||
|
||||
|
||||
array_list_t old_item;
|
||||
array_list_t session_item_list;
|
||||
int ignore_newline = 0;
|
||||
int do_push = 1;
|
||||
|
||||
|
||||
al_init( &old_item );
|
||||
al_init( &session_item_list );
|
||||
al_push_all( &old_item, &m->item );
|
||||
al_truncate( &m->item, 0 );
|
||||
|
||||
|
||||
for( pos = begin; pos <end; pos++ )
|
||||
{
|
||||
|
||||
|
||||
if( do_push )
|
||||
{
|
||||
item_t *i;
|
||||
|
@ -509,14 +509,14 @@ static void history_populate_from_mmap( history_mode_t *m )
|
|||
ignore_newline = *pos == '#';
|
||||
|
||||
i = item_get( m, pos );
|
||||
|
||||
if( (i_orig=hash_get( ¤t_mode->session_item, i ) ) )
|
||||
|
||||
if( (i_orig=(item_t *)hash_get( ¤t_mode->session_item, i ) ) )
|
||||
{
|
||||
/*
|
||||
This item comes from this session. Insert the
|
||||
original item at the end of the item list.
|
||||
*/
|
||||
al_push( &session_item_list, i_orig );
|
||||
al_push( &session_item_list, i_orig );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -525,10 +525,10 @@ static void history_populate_from_mmap( history_mode_t *m )
|
|||
*/
|
||||
al_push( &m->item, pos );
|
||||
}
|
||||
|
||||
|
||||
do_push = 0;
|
||||
}
|
||||
|
||||
|
||||
switch( *pos )
|
||||
{
|
||||
case '\\':
|
||||
|
@ -536,7 +536,7 @@ static void history_populate_from_mmap( history_mode_t *m )
|
|||
pos++;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case '\n':
|
||||
{
|
||||
if( ignore_newline )
|
||||
|
@ -546,12 +546,12 @@ static void history_populate_from_mmap( history_mode_t *m )
|
|||
else
|
||||
{
|
||||
do_push = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
al_push_all( &m->item, &session_item_list );
|
||||
m->pos += al_get_count( &m->item );
|
||||
al_push_all( &m->item, &old_item );
|
||||
|
@ -568,20 +568,20 @@ static void history_load( history_mode_t *m )
|
|||
{
|
||||
int fd;
|
||||
int ok=0;
|
||||
|
||||
|
||||
void *context;
|
||||
wchar_t *filename;
|
||||
|
||||
if( !m )
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
m->has_loaded=1;
|
||||
|
||||
signal_block();
|
||||
|
||||
context = halloc( 0, 0 );
|
||||
filename = history_filename( context, m->name, 0 );
|
||||
|
||||
|
||||
if( filename )
|
||||
{
|
||||
if( ( fd = wopen( filename, O_RDONLY ) ) > 0 )
|
||||
|
@ -592,7 +592,7 @@ static void history_load( history_mode_t *m )
|
|||
m->mmap_length = (size_t)len;
|
||||
if( lseek( fd, 0, SEEK_SET ) == 0 )
|
||||
{
|
||||
if( (m->mmap_start = mmap( 0, m->mmap_length, PROT_READ, MAP_PRIVATE, fd, 0 )) != MAP_FAILED )
|
||||
if( (m->mmap_start = (char *)mmap( 0, m->mmap_length, PROT_READ, MAP_PRIVATE, fd, 0 )) != MAP_FAILED )
|
||||
{
|
||||
ok = 1;
|
||||
history_populate_from_mmap( m );
|
||||
|
@ -602,7 +602,7 @@ static void history_load( history_mode_t *m )
|
|||
close( fd );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
halloc_free( context );
|
||||
signal_unblock();
|
||||
}
|
||||
|
@ -633,12 +633,12 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !has_new )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
|
@ -647,19 +647,19 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
*/
|
||||
on_disk = history_create_mode( m->name );
|
||||
history_load( on_disk );
|
||||
|
||||
|
||||
tmp_name = history_filename( on_disk, m->name, L".tmp" );
|
||||
|
||||
if( tmp_name )
|
||||
{
|
||||
tmp_name = wcsdup(tmp_name );
|
||||
|
||||
|
||||
if( (out=wfopen( tmp_name, "w" ) ) )
|
||||
{
|
||||
hash_table_t mine;
|
||||
|
||||
|
||||
hash_init( &mine, &hash_item_func, &hash_item_cmp );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count(&m->item); i++ )
|
||||
{
|
||||
void *ptr = al_get( &m->item, i );
|
||||
|
@ -669,7 +669,7 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
hash_put( &mine, item_get( m, ptr ), L"" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Re-save the old history
|
||||
*/
|
||||
|
@ -685,14 +685,14 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
hash_destroy( &mine );
|
||||
|
||||
|
||||
/*
|
||||
Add our own items last
|
||||
*/
|
||||
*/
|
||||
for( i=0; ok && (i<al_get_count(&m->item)); i++ )
|
||||
{
|
||||
void *ptr = al_get( &m->item, i );
|
||||
|
@ -700,12 +700,12 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
if( is_new )
|
||||
{
|
||||
if( item_write( out, m, ptr ) == -1 )
|
||||
{
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( fclose( out ) || !ok )
|
||||
{
|
||||
/*
|
||||
|
@ -720,8 +720,8 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
}
|
||||
}
|
||||
free( tmp_name );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
halloc_free( on_disk);
|
||||
|
||||
if( ok )
|
||||
|
@ -733,23 +733,23 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
hash table. On reload, they will be automatically inserted at
|
||||
the end of the history list.
|
||||
*/
|
||||
|
||||
|
||||
if( m->mmap_start && (m->mmap_start != MAP_FAILED ) )
|
||||
{
|
||||
munmap( m->mmap_start, m->mmap_length );
|
||||
}
|
||||
|
||||
|
||||
al_truncate( &m->item, 0 );
|
||||
al_truncate( &m->used, 0 );
|
||||
m->pos = 0;
|
||||
m->has_loaded = 0;
|
||||
m->mmap_start=0;
|
||||
m->mmap_length=0;
|
||||
|
||||
|
||||
m->save_timestamp=time(0);
|
||||
m->new_count = 0;
|
||||
}
|
||||
|
||||
|
||||
signal_unblock();
|
||||
}
|
||||
|
||||
|
@ -757,27 +757,27 @@ static void history_save_mode( void *n, history_mode_t *m )
|
|||
void history_add( const wchar_t *str )
|
||||
{
|
||||
item_t *i;
|
||||
|
||||
|
||||
if( !current_mode )
|
||||
return;
|
||||
|
||||
i = halloc( current_mode->item_context, sizeof(item_t));
|
||||
|
||||
i = (item_t *)halloc( current_mode->item_context, sizeof(item_t));
|
||||
i->data = (wchar_t *)halloc_wcsdup( current_mode->item_context, str );
|
||||
i->timestamp = time(0);
|
||||
|
||||
|
||||
al_push( ¤t_mode->item, i );
|
||||
hash_put( ¤t_mode->session_item, i, i );
|
||||
|
||||
|
||||
al_truncate( ¤t_mode->used, 0 );
|
||||
current_mode->pos = al_get_count( ¤t_mode->item );
|
||||
|
||||
current_mode->new_count++;
|
||||
|
||||
|
||||
if( (time(0) > current_mode->save_timestamp+SAVE_INTERVAL) || (current_mode->new_count >= SAVE_COUNT) )
|
||||
{
|
||||
history_save_mode( 0, current_mode );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -796,9 +796,9 @@ static int history_is_used( const wchar_t *str )
|
|||
if( wcscmp( it->data, str ) == 0 )
|
||||
{
|
||||
res = 1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -813,11 +813,11 @@ const wchar_t *history_prev_match( const wchar_t *needle )
|
|||
{
|
||||
item_t *i = item_get( current_mode, al_get( ¤t_mode->item, current_mode->pos ) );
|
||||
wchar_t *haystack = (wchar_t *)i->data;
|
||||
|
||||
|
||||
if( history_test( needle, haystack ) )
|
||||
{
|
||||
int is_used;
|
||||
|
||||
|
||||
/*
|
||||
This is ugly. Whenever we call item_get(),
|
||||
there is a chance that the return value of any
|
||||
|
@ -829,11 +829,11 @@ const wchar_t *history_prev_match( const wchar_t *needle )
|
|||
*/
|
||||
|
||||
haystack = wcsdup(haystack );
|
||||
|
||||
|
||||
is_used = history_is_used( haystack );
|
||||
|
||||
|
||||
free( haystack );
|
||||
|
||||
|
||||
if( !is_used )
|
||||
{
|
||||
i = item_get( current_mode, al_get( ¤t_mode->item, current_mode->pos ) );
|
||||
|
@ -843,7 +843,7 @@ const wchar_t *history_prev_match( const wchar_t *needle )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !current_mode->has_loaded )
|
||||
{
|
||||
/*
|
||||
|
@ -864,9 +864,9 @@ const wchar_t *history_prev_match( const wchar_t *needle )
|
|||
if( al_peek_long( ¤t_mode->used ) != -1 )
|
||||
al_push_long( ¤t_mode->used, -1 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return needle;
|
||||
}
|
||||
|
||||
|
@ -877,7 +877,7 @@ wchar_t *history_get( int idx )
|
|||
|
||||
if( !current_mode )
|
||||
return 0;
|
||||
|
||||
|
||||
len = al_get_count( ¤t_mode->item );
|
||||
|
||||
if( (idx >= len ) && !current_mode->has_loaded )
|
||||
|
@ -885,13 +885,13 @@ wchar_t *history_get( int idx )
|
|||
history_load( current_mode );
|
||||
len = al_get_count( ¤t_mode->item );
|
||||
}
|
||||
|
||||
|
||||
if( idx < 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
if( idx >= len )
|
||||
return 0;
|
||||
|
||||
|
||||
return item_get( current_mode, al_get( ¤t_mode->item, len - 1 - idx ) )->data;
|
||||
}
|
||||
|
||||
|
@ -903,9 +903,9 @@ void history_first()
|
|||
{
|
||||
history_load( current_mode );
|
||||
}
|
||||
|
||||
|
||||
current_mode->pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void history_reset()
|
||||
|
@ -917,7 +917,7 @@ void history_reset()
|
|||
Clear list of search matches
|
||||
*/
|
||||
al_truncate( ¤t_mode->used, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *history_next_match( const wchar_t *needle)
|
||||
|
@ -939,7 +939,7 @@ const wchar_t *history_next_match( const wchar_t *needle)
|
|||
return i->data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The used-list is empty. Set position to 'past end of list'
|
||||
and return the search string.
|
||||
|
@ -947,7 +947,7 @@ const wchar_t *history_next_match( const wchar_t *needle)
|
|||
current_mode->pos = al_get_count( ¤t_mode->item );
|
||||
|
||||
}
|
||||
return needle;
|
||||
return needle;
|
||||
}
|
||||
|
||||
|
||||
|
@ -955,17 +955,17 @@ void history_set_mode( const wchar_t *name )
|
|||
{
|
||||
if( !mode_table )
|
||||
{
|
||||
mode_table = malloc( sizeof(hash_table_t ));
|
||||
hash_init( mode_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
mode_table = (hash_table_t *)malloc( sizeof(hash_table_t ));
|
||||
hash_init( mode_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
|
||||
current_mode = (history_mode_t *)hash_get( mode_table, name );
|
||||
|
||||
|
||||
if( !current_mode )
|
||||
{
|
||||
current_mode = history_create_mode( name );
|
||||
hash_put( mode_table, name, current_mode );
|
||||
}
|
||||
hash_put( mode_table, name, current_mode );
|
||||
}
|
||||
}
|
||||
|
||||
void history_init()
|
||||
|
|
|
@ -50,7 +50,7 @@ void history_reset();
|
|||
|
||||
/**
|
||||
Find next history item starting with str. If this moves past
|
||||
the end of the history, str is returned.
|
||||
the end of the history, str is returned.
|
||||
*/
|
||||
const wchar_t *history_next_match( const wchar_t *str);
|
||||
|
||||
|
|
166
input.cpp
166
input.cpp
|
@ -74,7 +74,7 @@
|
|||
*/
|
||||
#define TERMINFO_ADD(key) \
|
||||
{ \
|
||||
terminfo_mapping_t *m = halloc( terminfo_mappings, sizeof( terminfo_mapping_t ) ); \
|
||||
terminfo_mapping_t *m = (terminfo_mapping_t *)halloc( terminfo_mappings, sizeof( terminfo_mapping_t ) ); \
|
||||
m->name = halloc_wcsdup( terminfo_mappings, (L ## #key)+4 ); \
|
||||
m->seq = key; \
|
||||
al_push( terminfo_mappings, m ); \
|
||||
|
@ -88,7 +88,7 @@ typedef struct
|
|||
{
|
||||
const wchar_t *seq; /**< Character sequence which generates this event */
|
||||
const wchar_t *command; /**< command that should be evaluated by this mapping */
|
||||
|
||||
|
||||
}
|
||||
input_mapping_t;
|
||||
|
||||
|
@ -99,7 +99,7 @@ typedef struct
|
|||
{
|
||||
const wchar_t *name; /**< Name of key */
|
||||
const char *seq; /**< Character sequence generated on keypress */
|
||||
|
||||
|
||||
}
|
||||
terminfo_mapping_t;
|
||||
|
||||
|
@ -107,7 +107,7 @@ typedef struct
|
|||
/**
|
||||
Names of all the input functions supported
|
||||
*/
|
||||
static const wchar_t *name_arr[] =
|
||||
static const wchar_t *name_arr[] =
|
||||
{
|
||||
L"beginning-of-line",
|
||||
L"end-of-line",
|
||||
|
@ -188,7 +188,7 @@ static const wchar_t *desc_arr[] =
|
|||
/**
|
||||
Internal code for each supported input function
|
||||
*/
|
||||
static const wchar_t code_arr[] =
|
||||
static const wchar_t code_arr[] =
|
||||
{
|
||||
R_BEGINNING_OF_LINE,
|
||||
R_END_OF_LINE,
|
||||
|
@ -230,7 +230,7 @@ static const wchar_t code_arr[] =
|
|||
/**
|
||||
Mappings for the current input mode
|
||||
*/
|
||||
static array_list_t mappings = {0,0,0};
|
||||
static array_list_t mappings = {0,0,0};
|
||||
|
||||
/**
|
||||
List of all terminfo mappings
|
||||
|
@ -239,7 +239,7 @@ static array_list_t *terminfo_mappings = 0;
|
|||
|
||||
|
||||
/**
|
||||
Set to one when the input subsytem has been initialized.
|
||||
Set to one when the input subsytem has been initialized.
|
||||
*/
|
||||
static int is_init = 0;
|
||||
|
||||
|
@ -263,9 +263,9 @@ void input_mapping_add( const wchar_t *sequence,
|
|||
|
||||
CHECK( sequence, );
|
||||
CHECK( command, );
|
||||
|
||||
|
||||
// debug( 0, L"Add mapping from %ls to %ls", escape(sequence, 1), escape(command, 1 ) );
|
||||
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &mappings); i++ )
|
||||
{
|
||||
|
@ -276,12 +276,12 @@ void input_mapping_add( const wchar_t *sequence,
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
input_mapping_t *m = malloc( sizeof( input_mapping_t ) );
|
||||
|
||||
input_mapping_t *m = (input_mapping_t *)malloc( sizeof( input_mapping_t ) );
|
||||
m->seq = intern( sequence );
|
||||
m->command = intern(command);
|
||||
al_push( &mappings, m );
|
||||
|
||||
al_push( &mappings, m );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -294,13 +294,13 @@ static int interrupt_handler()
|
|||
Fire any pending events
|
||||
*/
|
||||
event_fire( NULL );
|
||||
|
||||
|
||||
/*
|
||||
Reap stray processes, including printing exit status messages
|
||||
*/
|
||||
if( job_reap( 1 ) )
|
||||
reader_repaint_needed();
|
||||
|
||||
|
||||
/*
|
||||
Tell the reader an event occured
|
||||
*/
|
||||
|
@ -312,14 +312,14 @@ static int interrupt_handler()
|
|||
return 3;
|
||||
}
|
||||
|
||||
return R_NULL;
|
||||
return R_NULL;
|
||||
}
|
||||
|
||||
int input_init()
|
||||
{
|
||||
if( is_init )
|
||||
return 1;
|
||||
|
||||
|
||||
is_init = 1;
|
||||
|
||||
input_common_init( &interrupt_handler );
|
||||
|
@ -330,7 +330,7 @@ int input_init()
|
|||
exit(1);
|
||||
}
|
||||
output_set_term( env_get( L"TERM" ) );
|
||||
|
||||
|
||||
input_terminfo_init();
|
||||
|
||||
/*
|
||||
|
@ -353,22 +353,22 @@ void input_destroy()
|
|||
{
|
||||
if( !is_init )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
is_init=0;
|
||||
|
||||
al_foreach( &mappings, &free );
|
||||
|
||||
al_foreach( &mappings, &free );
|
||||
al_destroy( &mappings );
|
||||
|
||||
input_common_destroy();
|
||||
|
||||
|
||||
if( del_curterm( cur_term ) == ERR )
|
||||
{
|
||||
debug( 0, _(L"Error while closing terminfo") );
|
||||
}
|
||||
|
||||
input_terminfo_destroy();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,7 +378,7 @@ static wint_t input_exec_binding( input_mapping_t *m, const wchar_t *seq )
|
|||
{
|
||||
wchar_t code = input_function_get_code( m->command );
|
||||
if( code != -1 )
|
||||
{
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
|
||||
|
@ -386,37 +386,37 @@ static wint_t input_exec_binding( input_mapping_t *m, const wchar_t *seq )
|
|||
{
|
||||
return seq[0];
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
This key sequence is bound to a command, which
|
||||
is sent to the parser for evaluation.
|
||||
*/
|
||||
int last_status = proc_get_last_status();
|
||||
|
||||
|
||||
eval( m->command, 0, TOP );
|
||||
|
||||
|
||||
proc_set_last_status( last_status );
|
||||
|
||||
|
||||
/*
|
||||
We still need to return something to the caller, R_NULL
|
||||
tells the reader that no key press needs to be handled,
|
||||
tells the reader that no key press needs to be handled,
|
||||
and no repaint is needed.
|
||||
|
||||
Bindings that produce output should emit a R_REPAINT
|
||||
function by calling 'commandline -f repaint' to tell
|
||||
fish that a repaint is in order.
|
||||
fish that a repaint is in order.
|
||||
*/
|
||||
|
||||
|
||||
return R_NULL;
|
||||
|
||||
}
|
||||
|
@ -441,14 +441,14 @@ static wint_t input_try_mapping( input_mapping_t *m)
|
|||
return input_exec_binding( m, m->seq );
|
||||
}
|
||||
input_unreadch( c );
|
||||
|
||||
|
||||
if( m->seq != 0 )
|
||||
{
|
||||
|
||||
for( j=0; m->seq[j] != L'\0' &&
|
||||
for( j=0; m->seq[j] != L'\0' &&
|
||||
m->seq[j] == (c=input_common_readch( j>0 )); j++ )
|
||||
;
|
||||
|
||||
|
||||
if( m->seq[j] == L'\0' )
|
||||
{
|
||||
return input_exec_binding( m, m->seq );
|
||||
|
@ -466,7 +466,7 @@ static wint_t input_try_mapping( input_mapping_t *m)
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void input_unreadch( wint_t ch )
|
||||
|
@ -476,16 +476,16 @@ void input_unreadch( wint_t ch )
|
|||
|
||||
wint_t input_readch()
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
CHECK_BLOCK( R_NULL );
|
||||
|
||||
|
||||
/*
|
||||
Clear the interrupted flag
|
||||
*/
|
||||
reader_interrupted();
|
||||
|
||||
|
||||
/*
|
||||
Search for sequence in mapping tables
|
||||
*/
|
||||
|
@ -496,51 +496,51 @@ wint_t input_readch()
|
|||
for( i=0; i<al_get_count( &mappings); i++ )
|
||||
{
|
||||
input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
|
||||
wint_t res = input_try_mapping( m );
|
||||
wint_t res = input_try_mapping( m );
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
|
||||
if( wcslen( m->seq) == 0 )
|
||||
{
|
||||
generic = m;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
No matching exact mapping, try to find generic mapping.
|
||||
*/
|
||||
|
||||
if( generic )
|
||||
{
|
||||
{
|
||||
wchar_t arr[2]=
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}
|
||||
;
|
||||
arr[0] = input_common_readch(0);
|
||||
|
||||
return input_exec_binding( generic, arr );
|
||||
|
||||
return input_exec_binding( generic, arr );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
No action to take on specified character, ignore it
|
||||
and move to next one.
|
||||
*/
|
||||
input_common_readch( 0 ); }
|
||||
input_common_readch( 0 ); }
|
||||
}
|
||||
|
||||
void input_mapping_get_names( array_list_t *list )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &mappings ); i++ )
|
||||
{
|
||||
input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
|
||||
al_push( list, m->seq );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -549,7 +549,7 @@ int input_mapping_erase( const wchar_t *sequence )
|
|||
int ok = 0;
|
||||
int i;
|
||||
size_t sz = al_get_count( &mappings );
|
||||
|
||||
|
||||
for( i=0; i<sz; i++ )
|
||||
{
|
||||
input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
|
||||
|
@ -561,24 +561,24 @@ int input_mapping_erase( const wchar_t *sequence )
|
|||
}
|
||||
al_truncate( &mappings, sz-1 );
|
||||
ok = 1;
|
||||
|
||||
|
||||
free( m );
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
|
||||
}
|
||||
|
||||
const wchar_t *input_mapping_get( const wchar_t *sequence )
|
||||
{
|
||||
int i;
|
||||
size_t sz = al_get_count( &mappings );
|
||||
|
||||
|
||||
for( i=0; i<sz; i++ )
|
||||
{
|
||||
input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
|
||||
|
@ -596,7 +596,7 @@ const wchar_t *input_mapping_get( const wchar_t *sequence )
|
|||
static void input_terminfo_init()
|
||||
{
|
||||
terminfo_mappings = al_halloc( 0 );
|
||||
|
||||
|
||||
|
||||
TERMINFO_ADD(key_a1);
|
||||
TERMINFO_ADD(key_a3);
|
||||
|
@ -758,7 +758,7 @@ static void input_terminfo_init()
|
|||
|
||||
static void input_terminfo_destroy()
|
||||
{
|
||||
|
||||
|
||||
if( terminfo_mappings )
|
||||
{
|
||||
halloc_free( terminfo_mappings );
|
||||
|
@ -768,17 +768,17 @@ static void input_terminfo_destroy()
|
|||
const wchar_t *input_terminfo_get_sequence( const wchar_t *name )
|
||||
{
|
||||
const char *res = 0;
|
||||
int i;
|
||||
int i;
|
||||
static string_buffer_t *buff = 0;
|
||||
int err = ENOENT;
|
||||
|
||||
|
||||
CHECK( name, 0 );
|
||||
input_init();
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( terminfo_mappings ); i++ )
|
||||
{
|
||||
terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
|
||||
|
||||
|
||||
if( !wcscmp( name, m->name ) )
|
||||
{
|
||||
res = m->seq;
|
||||
|
@ -786,71 +786,71 @@ const wchar_t *input_terminfo_get_sequence( const wchar_t *name )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !res )
|
||||
{
|
||||
errno = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( !buff )
|
||||
{
|
||||
buff = sb_halloc( global_context );
|
||||
}
|
||||
|
||||
|
||||
sb_clear( buff );
|
||||
sb_printf( buff, L"%s", res );
|
||||
|
||||
return (wchar_t *)buff->buff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
const wchar_t *input_terminfo_get_name( const wchar_t *seq )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
static string_buffer_t *buff = 0;
|
||||
|
||||
CHECK( seq, 0 );
|
||||
input_init();
|
||||
|
||||
|
||||
if( !buff )
|
||||
{
|
||||
buff = sb_halloc( global_context );
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( terminfo_mappings ); i++ )
|
||||
{
|
||||
terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
|
||||
|
||||
|
||||
if( !m->seq )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
sb_clear( buff );
|
||||
sb_printf( buff, L"%s", m->seq );
|
||||
|
||||
|
||||
if( !wcscmp( seq, (wchar_t *)buff->buff ) )
|
||||
{
|
||||
return m->name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void input_terminfo_get_names( array_list_t *lst, int skip_null )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
CHECK( lst, );
|
||||
input_init();
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( terminfo_mappings ); i++ )
|
||||
{
|
||||
terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
|
||||
|
||||
|
||||
if( skip_null && !m->seq )
|
||||
{
|
||||
continue;
|
||||
|
@ -861,10 +861,10 @@ void input_terminfo_get_names( array_list_t *lst, int skip_null )
|
|||
|
||||
void input_function_get_names( array_list_t *lst )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
CHECK( lst, );
|
||||
|
||||
|
||||
for( i=0; i<(sizeof(name_arr)/sizeof(wchar_t *)); i++ )
|
||||
{
|
||||
al_push( lst, name_arr[i] );
|
||||
|
@ -882,6 +882,6 @@ wchar_t input_function_get_code( const wchar_t *name )
|
|||
return code_arr[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
2
input.h
2
input.h
|
@ -83,7 +83,7 @@ wint_t input_readch();
|
|||
/**
|
||||
Push a character or a readline function onto the stack of unread
|
||||
characters that input_readch will return before actually reading from fd
|
||||
0.
|
||||
0.
|
||||
*/
|
||||
void input_unreadch( wint_t ch );
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/** \file input_common.c
|
||||
|
||||
|
||||
Implementation file for the low level input library
|
||||
|
||||
*/
|
||||
|
@ -55,7 +55,7 @@ void input_common_init( int (*ih)() )
|
|||
|
||||
void input_common_destroy()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,13 +66,13 @@ static wint_t readb()
|
|||
{
|
||||
unsigned char arr[1];
|
||||
int do_loop = 0;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
fd_set fd;
|
||||
int fd_max=1;
|
||||
int res;
|
||||
|
||||
|
||||
FD_ZERO( &fd );
|
||||
FD_SET( 0, &fd );
|
||||
if( env_universal_server.fd > 0 )
|
||||
|
@ -80,9 +80,9 @@ static wint_t readb()
|
|||
FD_SET( env_universal_server.fd, &fd );
|
||||
fd_max = env_universal_server.fd+1;
|
||||
}
|
||||
|
||||
do_loop = 0;
|
||||
|
||||
|
||||
do_loop = 0;
|
||||
|
||||
res = select( fd_max, &fd, 0, 0, 0 );
|
||||
if( res==-1 )
|
||||
{
|
||||
|
@ -102,10 +102,10 @@ static wint_t readb()
|
|||
{
|
||||
return lookahead_arr[--lookahead_count];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
do_loop = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static wint_t readb()
|
|||
*/
|
||||
return R_EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -124,7 +124,7 @@ static wint_t readb()
|
|||
{
|
||||
if( FD_ISSET( env_universal_server.fd, &fd ) )
|
||||
{
|
||||
debug( 3, L"Wake up on universal variable event" );
|
||||
debug( 3, L"Wake up on universal variable event" );
|
||||
env_universal_read_all();
|
||||
do_loop = 1;
|
||||
|
||||
|
@ -132,7 +132,7 @@ static wint_t readb()
|
|||
{
|
||||
return lookahead_arr[--lookahead_count];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( FD_ISSET( 0, &fd ) )
|
||||
{
|
||||
|
@ -144,11 +144,11 @@ static wint_t readb()
|
|||
return R_EOF;
|
||||
}
|
||||
do_loop = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while( do_loop );
|
||||
|
||||
|
||||
return arr[0];
|
||||
}
|
||||
|
||||
|
@ -167,16 +167,16 @@ wchar_t input_common_readch( int timed )
|
|||
1000 * WAIT_ON_ESCAPE
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( 0, &fds );
|
||||
count = select(1, &fds, 0, 0, &tm);
|
||||
|
||||
|
||||
switch( count )
|
||||
{
|
||||
case 0:
|
||||
return WEOF;
|
||||
|
||||
|
||||
case -1:
|
||||
return WEOF;
|
||||
break;
|
||||
|
@ -185,7 +185,7 @@ wchar_t input_common_readch( int timed )
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wchar_t res;
|
||||
static mbstate_t state;
|
||||
|
||||
|
@ -193,33 +193,33 @@ wchar_t input_common_readch( int timed )
|
|||
{
|
||||
wint_t b = readb();
|
||||
char bb;
|
||||
|
||||
|
||||
int sz;
|
||||
|
||||
|
||||
if( (b >= R_NULL) && (b < R_NULL + 1000) )
|
||||
return b;
|
||||
|
||||
bb=b;
|
||||
|
||||
|
||||
sz = mbrtowc( &res, &bb, 1, &state );
|
||||
|
||||
|
||||
switch( sz )
|
||||
{
|
||||
case -1:
|
||||
memset (&state, '\0', sizeof (state));
|
||||
debug( 2, L"Illegal input" );
|
||||
return R_NULL;
|
||||
debug( 2, L"Illegal input" );
|
||||
return R_NULL;
|
||||
case -2:
|
||||
break;
|
||||
case 0:
|
||||
return 0;
|
||||
default:
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if( !timed )
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ wchar_t input_common_readch( int timed )
|
|||
if( lookahead_count == 0 )
|
||||
return input_common_readch(0);
|
||||
}
|
||||
|
||||
|
||||
return lookahead_arr[--lookahead_count];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/** \file input_common.h
|
||||
|
||||
|
||||
Header file for the low level input library
|
||||
|
||||
*/
|
||||
|
|
50
intern.cpp
50
intern.cpp
|
@ -33,29 +33,29 @@ const wchar_t *intern( const wchar_t *in )
|
|||
const wchar_t *res=0;
|
||||
|
||||
// debug( 0, L"intern %ls", in );
|
||||
|
||||
|
||||
if( !in )
|
||||
return 0;
|
||||
|
||||
|
||||
if( !intern_table )
|
||||
{
|
||||
intern_table = malloc( sizeof( hash_table_t ) );
|
||||
intern_table = (hash_table_t *)malloc( sizeof( hash_table_t ) );
|
||||
if( !intern_table )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
hash_init( intern_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
|
||||
if( intern_static_table )
|
||||
{
|
||||
res = hash_get( intern_static_table, in );
|
||||
res = (const wchar_t *)hash_get( intern_static_table, in );
|
||||
}
|
||||
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = hash_get( intern_table, in );
|
||||
|
||||
res = (const wchar_t *)hash_get( intern_table, in );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = wcsdup( in );
|
||||
|
@ -63,39 +63,39 @@ const wchar_t *intern( const wchar_t *in )
|
|||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
|
||||
hash_put( intern_table, res, res );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const wchar_t *intern_static( const wchar_t *in )
|
||||
{
|
||||
const wchar_t *res=0;
|
||||
|
||||
|
||||
if( !in )
|
||||
return 0;
|
||||
|
||||
|
||||
if( !intern_static_table )
|
||||
{
|
||||
intern_static_table = malloc( sizeof( hash_table_t ) );
|
||||
intern_static_table = (hash_table_t *)malloc( sizeof( hash_table_t ) );
|
||||
if( !intern_static_table )
|
||||
{
|
||||
DIE_MEM();
|
||||
DIE_MEM();
|
||||
}
|
||||
hash_init( intern_static_table, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
res = hash_get( intern_static_table, in );
|
||||
|
||||
|
||||
res = (const wchar_t *)hash_get( intern_static_table, in );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = in;
|
||||
hash_put( intern_static_table, res, res );
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ const wchar_t *intern_static( const wchar_t *in )
|
|||
*/
|
||||
static void clear_value( void *key, void *data )
|
||||
{
|
||||
debug( 3, L"interned string: '%ls'", data );
|
||||
debug( 3, L"interned string: '%ls'", data );
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
|
@ -112,17 +112,17 @@ void intern_free_all()
|
|||
{
|
||||
if( intern_table )
|
||||
{
|
||||
hash_foreach( intern_table, &clear_value );
|
||||
hash_destroy( intern_table );
|
||||
hash_foreach( intern_table, &clear_value );
|
||||
hash_destroy( intern_table );
|
||||
free( intern_table );
|
||||
intern_table=0;
|
||||
intern_table=0;
|
||||
}
|
||||
|
||||
if( intern_static_table )
|
||||
{
|
||||
hash_destroy( intern_static_table );
|
||||
hash_destroy( intern_static_table );
|
||||
free( intern_static_table );
|
||||
intern_static_table=0;
|
||||
intern_static_table=0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
56
io.cpp
56
io.cpp
|
@ -1,7 +1,7 @@
|
|||
/** \file io.c
|
||||
|
||||
Utilities for io redirection.
|
||||
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@ void io_buffer_read( io_data_t *d )
|
|||
exec_close(d->param1.pipe_fd[1] );
|
||||
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
{
|
||||
{
|
||||
/* if( fcntl( d->param1.pipe_fd[0], F_SETFL, 0 ) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
|
@ -83,17 +83,17 @@ void io_buffer_read( io_data_t *d )
|
|||
*/
|
||||
if( errno != EAGAIN )
|
||||
{
|
||||
debug( 1,
|
||||
_(L"An error occured while reading output from code block on file descriptor %d"),
|
||||
debug( 1,
|
||||
_(L"An error occured while reading output from code block on file descriptor %d"),
|
||||
d->param1.pipe_fd[0] );
|
||||
wperror( L"io_buffer_read" );
|
||||
wperror( L"io_buffer_read" );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_append( d->param2.out_buffer, b, l );
|
||||
{
|
||||
b_append( d->param2.out_buffer, b, l );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,15 +102,15 @@ void io_buffer_read( io_data_t *d )
|
|||
|
||||
io_data_t *io_buffer_create( int is_input )
|
||||
{
|
||||
io_data_t *buffer_redirect = malloc( sizeof( io_data_t ));
|
||||
|
||||
io_data_t *buffer_redirect = (io_data_t *)malloc( sizeof( io_data_t ));
|
||||
|
||||
buffer_redirect->io_mode=IO_BUFFER;
|
||||
buffer_redirect->next=0;
|
||||
buffer_redirect->param2.out_buffer= malloc( sizeof(buffer_t));
|
||||
buffer_redirect->param2.out_buffer= (buffer_t *)malloc( sizeof(buffer_t));
|
||||
buffer_redirect->is_input = is_input;
|
||||
b_init( buffer_redirect->param2.out_buffer );
|
||||
buffer_redirect->fd=is_input?0:1;
|
||||
|
||||
|
||||
if( exec_pipe( buffer_redirect->param1.pipe_fd ) == -1 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
|
@ -150,9 +150,9 @@ void io_buffer_destroy( io_data_t *io_buffer )
|
|||
Dont free fd for writing. This should already be free'd before
|
||||
calling exec_read_io_buffer on the buffer
|
||||
*/
|
||||
|
||||
|
||||
b_destroy( io_buffer->param2.out_buffer );
|
||||
|
||||
|
||||
free( io_buffer->param2.out_buffer );
|
||||
free( io_buffer );
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ io_data_t *io_remove( io_data_t *list, io_data_t *element )
|
|||
{
|
||||
io_data_t *curr, *prev=0;
|
||||
for( curr=list; curr; curr = curr->next )
|
||||
{
|
||||
{
|
||||
if( element == curr )
|
||||
{
|
||||
if( prev == 0 )
|
||||
|
@ -198,32 +198,32 @@ io_data_t *io_remove( io_data_t *list, io_data_t *element )
|
|||
io_data_t *io_duplicate( void *context, io_data_t *l )
|
||||
{
|
||||
io_data_t *res;
|
||||
|
||||
|
||||
if( l == 0 )
|
||||
return 0;
|
||||
|
||||
res = halloc( context, sizeof( io_data_t) );
|
||||
|
||||
res = (io_data_t *)halloc( context, sizeof( io_data_t) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
memcpy( res, l, sizeof(io_data_t ));
|
||||
res->next=io_duplicate( context, l->next );
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
io_data_t *io_get( io_data_t *io, int fd )
|
||||
{
|
||||
if( io == 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
io_data_t *res = io_get( io->next, fd );
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
|
||||
if( io->fd == fd )
|
||||
return io;
|
||||
|
||||
|
@ -237,14 +237,14 @@ void io_print( io_data_t *io )
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
debug( 1, L"IO fd %d, type ", io->fd );
|
||||
switch( io->io_mode )
|
||||
{
|
||||
case IO_PIPE:
|
||||
debug( 1, L"PIPE, data %d", io->param1.pipe_fd[io->fd?1:0] );
|
||||
break;
|
||||
|
||||
|
||||
case IO_FD:
|
||||
debug( 1, L"FD, copy %d", io->param1.old_fd );
|
||||
break;
|
||||
|
@ -252,11 +252,11 @@ void io_print( io_data_t *io )
|
|||
case IO_BUFFER:
|
||||
debug( 1, L"BUFFER" );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
debug( 1, L"OTHER" );
|
||||
}
|
||||
|
||||
io_print( io->next );
|
||||
|
||||
|
||||
}
|
||||
|
|
12
io.h
12
io.h
|
@ -17,8 +17,8 @@ typedef struct io_data
|
|||
int io_mode;
|
||||
/** FD to redirect */
|
||||
int fd;
|
||||
/**
|
||||
Type-specific parameter for redirection
|
||||
/**
|
||||
Type-specific parameter for redirection
|
||||
*/
|
||||
union
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ typedef struct io_data
|
|||
int old_fd;
|
||||
} param1
|
||||
;
|
||||
/**
|
||||
/**
|
||||
Second type-specific paramter for redirection
|
||||
*/
|
||||
union
|
||||
|
@ -38,7 +38,7 @@ typedef struct io_data
|
|||
/** file creation flags to send to open for IO_FILE */
|
||||
int flags;
|
||||
/** buffer to save output in for IO_BUFFER */
|
||||
buffer_t *out_buffer;
|
||||
buffer_t *out_buffer;
|
||||
/** Whether to close old_fd for IO_FD */
|
||||
int close_old;
|
||||
} param2
|
||||
|
@ -48,13 +48,13 @@ typedef struct io_data
|
|||
Set to true if this is an input io redirection
|
||||
*/
|
||||
int is_input;
|
||||
|
||||
|
||||
/** Pointer to the next IO redirection */
|
||||
struct io_data *next;
|
||||
}
|
||||
io_data_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Join two chains of io redirections
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,7 @@ int main( int argc, char **argv)
|
|||
{
|
||||
|
||||
setlocale( LC_ALL, "" );
|
||||
|
||||
|
||||
|
||||
if( argc == 2 )
|
||||
{
|
||||
|
@ -37,24 +37,24 @@ int main( int argc, char **argv)
|
|||
char *termtype = getenv ("TERM");
|
||||
char *tbuff = malloc( sizeof(char)*9999);
|
||||
char *res;
|
||||
|
||||
|
||||
tgetent( term_buffer, termtype );
|
||||
res = tgetstr( argv[1], &tbuff );
|
||||
res = tgetstr( argv[1], &tbuff );
|
||||
if( res != 0 )
|
||||
{
|
||||
while( *res != 0 )
|
||||
{
|
||||
{
|
||||
printf("%d ", *res );
|
||||
|
||||
|
||||
res++;
|
||||
}
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Undefined sequence\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -65,11 +65,11 @@ int main( int argc, char **argv)
|
|||
savemodes; /* so we can reset the modes when we're done */
|
||||
|
||||
input_common_init(0);
|
||||
|
||||
|
||||
|
||||
tcgetattr(0,&modes); /* get the current terminal modes */
|
||||
savemodes = modes; /* save a copy so we can reset them */
|
||||
|
||||
|
||||
modes.c_lflag &= ~ICANON; /* turn off canonical mode */
|
||||
modes.c_lflag &= ~ECHO; /* turn off echo mode */
|
||||
modes.c_cc[VMIN]=1;
|
||||
|
@ -83,13 +83,13 @@ int main( int argc, char **argv)
|
|||
sprintf( scratch, "dec: %d hex: %x char: %c\n", c, c, c );
|
||||
else
|
||||
sprintf( scratch, "dec: %d hex: %x\n", c, c );
|
||||
writestr( scratch );
|
||||
writestr( scratch );
|
||||
}
|
||||
/* reset the terminal to the saved mode */
|
||||
tcsetattr(0,TCSANOW,&savemodes);
|
||||
tcsetattr(0,TCSANOW,&savemodes);
|
||||
|
||||
input_common_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
88
kill.cpp
88
kill.cpp
|
@ -54,12 +54,12 @@ static int has_xsel()
|
|||
static int res = 0;
|
||||
|
||||
if (!called) {
|
||||
void *context = halloc(0, 0);
|
||||
wchar_t *path = path_get_path( context, L"xsel" );
|
||||
void *context = halloc(0, 0);
|
||||
wchar_t *path = path_get_path( context, L"xsel" );
|
||||
res = !!path;
|
||||
halloc_free( context );
|
||||
halloc_free( context );
|
||||
called = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -71,16 +71,16 @@ static void kill_add_internal( wchar_t *str )
|
|||
{
|
||||
if( wcslen( str ) == 0 )
|
||||
return;
|
||||
|
||||
|
||||
if( kill_last == 0 )
|
||||
{
|
||||
kill_current = kill_last=malloc( sizeof( ll_node_t ) );
|
||||
kill_current = kill_last=(ll_node_t *)malloc( sizeof( ll_node_t ) );
|
||||
kill_current->data = wcsdup(str);
|
||||
kill_current->prev = kill_current;
|
||||
}
|
||||
else
|
||||
{
|
||||
kill_current = malloc( sizeof( ll_node_t ) );
|
||||
kill_current = (ll_node_t *)malloc( sizeof( ll_node_t ) );
|
||||
kill_current->data = kill_last->data;
|
||||
kill_last->data = wcsdup(str);
|
||||
kill_current->prev = kill_last->prev;
|
||||
|
@ -112,14 +112,14 @@ void kill_add( wchar_t *str )
|
|||
}
|
||||
else
|
||||
{
|
||||
/* This is for sending the kill to the X copy-and-paste buffer */
|
||||
/* This is for sending the kill to the X copy-and-paste buffer */
|
||||
if( !has_xsel() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t *disp;
|
||||
if( (disp = env_get( L"DISPLAY" )) )
|
||||
{
|
||||
wchar_t *disp;
|
||||
if( (disp = env_get( L"DISPLAY" )) )
|
||||
{
|
||||
escaped_str = escape( str, 1 );
|
||||
cmd = wcsdupcat(L"echo ", escaped_str, L"|xsel -b" );
|
||||
}
|
||||
|
@ -129,14 +129,14 @@ void kill_add( wchar_t *str )
|
|||
{
|
||||
if( exec_subshell( cmd, 0 ) == -1 )
|
||||
{
|
||||
/*
|
||||
Do nothing on failiure
|
||||
/*
|
||||
Do nothing on failiure
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
free( cut_buffer );
|
||||
free( cmd );
|
||||
|
||||
|
||||
cut_buffer = escaped_str;
|
||||
}
|
||||
}
|
||||
|
@ -164,8 +164,8 @@ static void kill_remove_node( ll_node_t *n )
|
|||
}
|
||||
kill_current=kill_last;
|
||||
free( n->data );
|
||||
free( n );
|
||||
}
|
||||
free( n );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,13 +174,13 @@ static void kill_remove_node( ll_node_t *n )
|
|||
static void kill_remove( wchar_t *s )
|
||||
{
|
||||
ll_node_t *n, *next=0;
|
||||
|
||||
|
||||
if( !kill_last )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( n=kill_last;
|
||||
|
||||
for( n=kill_last;
|
||||
n!=kill_last || next == 0 ;
|
||||
n=n->prev )
|
||||
{
|
||||
|
@ -192,13 +192,13 @@ static void kill_remove( wchar_t *s )
|
|||
next = n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void kill_replace( wchar_t *old, wchar_t *new )
|
||||
void kill_replace( wchar_t *old, wchar_t *newv )
|
||||
{
|
||||
kill_remove( old );
|
||||
kill_add( new );
|
||||
kill_add( newv );
|
||||
}
|
||||
|
||||
wchar_t *kill_yank_rotate()
|
||||
|
@ -214,13 +214,13 @@ wchar_t *kill_yank_rotate()
|
|||
clipboard contents to the fish killring.
|
||||
*/
|
||||
static void kill_check_x_buffer()
|
||||
{
|
||||
{
|
||||
wchar_t *disp;
|
||||
|
||||
|
||||
if( !has_xsel() )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
if( (disp = env_get( L"DISPLAY" )) )
|
||||
{
|
||||
int i;
|
||||
|
@ -230,7 +230,7 @@ static void kill_check_x_buffer()
|
|||
al_init( &list );
|
||||
if( exec_subshell( cmd, &list ) != -1 )
|
||||
{
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &list ); i++ )
|
||||
{
|
||||
wchar_t *next_line = escape( (wchar_t *)al_get( &list, i ), 0 );
|
||||
|
@ -243,20 +243,20 @@ static void kill_check_x_buffer()
|
|||
wchar_t *old = new_cut_buffer;
|
||||
new_cut_buffer= wcsdupcat( new_cut_buffer, L"\\n", next_line );
|
||||
free( old );
|
||||
free( next_line );
|
||||
free( next_line );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( new_cut_buffer )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
The buffer is inserted with backslash escapes,
|
||||
since we don't really like tabs, newlines,
|
||||
etc. anyway.
|
||||
*/
|
||||
|
||||
|
||||
if( cut_buffer != 0 )
|
||||
{
|
||||
{
|
||||
if( wcscmp( new_cut_buffer, cut_buffer ) == 0 )
|
||||
{
|
||||
free( new_cut_buffer );
|
||||
|
@ -265,7 +265,7 @@ static void kill_check_x_buffer()
|
|||
else
|
||||
{
|
||||
free( cut_buffer );
|
||||
cut_buffer = 0;
|
||||
cut_buffer = 0;
|
||||
}
|
||||
}
|
||||
if( cut_buffer == 0 )
|
||||
|
@ -275,7 +275,7 @@ static void kill_check_x_buffer()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_foreach( &list, &free );
|
||||
al_destroy( &list );
|
||||
}
|
||||
|
@ -307,22 +307,22 @@ void kill_sanity_check()
|
|||
break;
|
||||
if( tmp->data == 0 )
|
||||
break;
|
||||
|
||||
|
||||
if( tmp == kill_current )
|
||||
{
|
||||
kill_ok = 1;
|
||||
break;
|
||||
}
|
||||
tmp = tmp->prev;
|
||||
tmp = tmp->prev;
|
||||
}
|
||||
if( !kill_ok )
|
||||
{
|
||||
debug( 0,
|
||||
debug( 0,
|
||||
L"Killring inconsistent" );
|
||||
sanity_lose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,12 +334,12 @@ void kill_destroy()
|
|||
{
|
||||
if( cut_buffer )
|
||||
free( cut_buffer );
|
||||
|
||||
|
||||
if( kill_current != 0 )
|
||||
{
|
||||
kill_current = kill_last->prev;
|
||||
kill_last->prev = 0;
|
||||
|
||||
|
||||
while( kill_current )
|
||||
{
|
||||
ll_node_t *tmp = kill_current;
|
||||
|
@ -347,7 +347,7 @@ void kill_destroy()
|
|||
free( tmp->data );
|
||||
free( tmp );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
2
kill.h
2
kill.h
|
@ -12,7 +12,7 @@
|
|||
/**
|
||||
Replace the specified string in the killring
|
||||
*/
|
||||
void kill_replace( wchar_t *old, wchar_t *new );
|
||||
void kill_replace( wchar_t *old, wchar_t *newv );
|
||||
|
||||
|
||||
/**
|
||||
|
|
358
mimedb.cpp
358
mimedb.cpp
|
@ -1,8 +1,8 @@
|
|||
/** \file mimedb.c
|
||||
/** \file mimedb.c
|
||||
|
||||
mimedb is a program for checking the mimetype, description and
|
||||
default action associated with a file or mimetype. It uses the
|
||||
xdgmime library written by the fine folks at freedesktop.org. There does
|
||||
xdgmime library written by the fine folks at freedesktop.org. There does
|
||||
not seem to be any standard way for the user to change the preferred
|
||||
application yet.
|
||||
|
||||
|
@ -97,7 +97,7 @@ license. Read the source code of the library for more information.
|
|||
/**
|
||||
Error message if system call goes wrong.
|
||||
*/
|
||||
#define ERROR_SYSTEM "%s: Could not execute command \"%s\"\n"
|
||||
#define ERROR_SYSTEM "%s: Could not execute command \"%s\"\n"
|
||||
|
||||
/**
|
||||
Exit code if system call goes wrong.
|
||||
|
@ -194,8 +194,8 @@ static char * search_ini( const char *filename, const char *match )
|
|||
FILE *f = fopen( filename, "r" );
|
||||
char buf[4096];
|
||||
int len=strlen(match);
|
||||
int done = 0;
|
||||
|
||||
int done = 0;
|
||||
|
||||
if(!f )
|
||||
{
|
||||
perror( "fopen" );
|
||||
|
@ -210,14 +210,14 @@ static char * search_ini( const char *filename, const char *match )
|
|||
{
|
||||
perror( "fgets" );
|
||||
error=1;
|
||||
}
|
||||
}
|
||||
buf[0]=0;
|
||||
done = 1;
|
||||
}
|
||||
else if( strncmp( buf, match, len ) == 0 && buf[len] == '=' )
|
||||
{
|
||||
done=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose( f );
|
||||
if( buf[0] )
|
||||
|
@ -242,36 +242,36 @@ static char *file_exists( const char *dir, const char *in )
|
|||
{
|
||||
int dir_len = strlen( dir );
|
||||
int need_sep = dir[dir_len - 1] != '/';
|
||||
char *filename = my_malloc( dir_len + need_sep + strlen( in ) + 1 );
|
||||
char *replaceme;
|
||||
char *filename = (char *)my_malloc( dir_len + need_sep + strlen( in ) + 1 );
|
||||
char *replaceme;
|
||||
struct stat buf;
|
||||
|
||||
// fprintf( stderr, "Check %s%s\n", dir, in );
|
||||
|
||||
|
||||
if( !filename )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
strcpy( filename, dir );
|
||||
if ( need_sep )
|
||||
filename[dir_len++] = '/';
|
||||
strcpy( filename + dir_len, in );
|
||||
|
||||
|
||||
if( !stat( filename, &buf ) )
|
||||
return filename;
|
||||
|
||||
free( filename );
|
||||
|
||||
|
||||
/*
|
||||
DOH! File does not exist. But all is not lost. KDE sometimes uses
|
||||
a slash in the name as a directory separator. We try to replace
|
||||
a dash with a slash and try again.
|
||||
a dash with a slash and try again.
|
||||
*/
|
||||
replaceme = strchr( in, '-' );
|
||||
replaceme = strchr( in, '-' );
|
||||
if( replaceme )
|
||||
{
|
||||
char *res;
|
||||
|
||||
|
||||
*replaceme = '/';
|
||||
res = file_exists( dir, in );
|
||||
*replaceme = '-';
|
||||
|
@ -306,8 +306,8 @@ static int append_filenames( array_list_t *list, char *f, int all )
|
|||
xdg_data_home = getenv ("XDG_DATA_HOME");
|
||||
if (xdg_data_home)
|
||||
{
|
||||
result = file_exists( xdg_data_home, f );
|
||||
if ( result )
|
||||
result = file_exists( xdg_data_home, f );
|
||||
if (result)
|
||||
{
|
||||
al_push( list, result );
|
||||
if ( !all )
|
||||
|
@ -323,16 +323,16 @@ static int append_filenames( array_list_t *list, char *f, int all )
|
|||
{
|
||||
char *guessed_xdg_home;
|
||||
|
||||
guessed_xdg_home = my_malloc (strlen (home) + strlen ("/.local/share") + 1);
|
||||
guessed_xdg_home = (char *)my_malloc (strlen (home) + strlen ("/.local/share") + 1);
|
||||
if( !guessed_xdg_home )
|
||||
return 0;
|
||||
|
||||
|
||||
strcpy (guessed_xdg_home, home);
|
||||
strcat (guessed_xdg_home, "/.local/share");
|
||||
result = file_exists( guessed_xdg_home, f );
|
||||
result = file_exists( guessed_xdg_home, f );
|
||||
free (guessed_xdg_home);
|
||||
|
||||
if ( result )
|
||||
if (result)
|
||||
{
|
||||
al_push( list, result );
|
||||
if ( !all )
|
||||
|
@ -363,18 +363,18 @@ static int append_filenames( array_list_t *list, char *f, int all )
|
|||
continue;
|
||||
}
|
||||
|
||||
len = end_ptr - ptr;
|
||||
dir = my_malloc (len + 1);
|
||||
len = end_ptr - ptr;
|
||||
dir = (char *)my_malloc (len + 1);
|
||||
if( !dir )
|
||||
return 0;
|
||||
|
||||
|
||||
strncpy (dir, ptr, len);
|
||||
dir[len] = '\0';
|
||||
result = file_exists( dir, f );
|
||||
|
||||
result = file_exists( dir, f );
|
||||
|
||||
free (dir);
|
||||
|
||||
if ( result )
|
||||
if (result)
|
||||
{
|
||||
al_push( list, result );
|
||||
if ( !all ) {
|
||||
|
@ -397,7 +397,7 @@ static char *get_filename( char *f )
|
|||
|
||||
al_init( &list );
|
||||
append_filenames( &list, f, 0 );
|
||||
first = al_pop( &list );
|
||||
first = (char *)al_pop( &list );
|
||||
al_destroy( &list );
|
||||
return first;
|
||||
}
|
||||
|
@ -409,7 +409,7 @@ static char *get_filename( char *f )
|
|||
*/
|
||||
static char *munge( char *in )
|
||||
{
|
||||
char *out = my_malloc( strlen( in )+1 );
|
||||
char *out = (char *)my_malloc( strlen( in )+1 );
|
||||
char *p=out;
|
||||
int had_whitespace = 0;
|
||||
int printed = 0;
|
||||
|
@ -417,11 +417,11 @@ static char *munge( char *in )
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// fprintf( stderr, "%c\n", *in );
|
||||
|
||||
|
||||
switch( *in )
|
||||
{
|
||||
case ' ':
|
||||
|
@ -442,7 +442,7 @@ static char *munge( char *in )
|
|||
*(p++)=' ';
|
||||
}
|
||||
printed=1;
|
||||
had_whitespace=0;
|
||||
had_whitespace=0;
|
||||
*(p++)=*in;
|
||||
break;
|
||||
}
|
||||
|
@ -459,19 +459,19 @@ static char *munge( char *in )
|
|||
*/
|
||||
static char *get_lang_re()
|
||||
{
|
||||
|
||||
|
||||
static char buff[BUFF_SIZE];
|
||||
const char *lang = setlocale( LC_MESSAGES, 0 );
|
||||
int close=0;
|
||||
char *out=buff;
|
||||
|
||||
|
||||
if( (1+strlen(lang)*4) >= BUFF_SIZE )
|
||||
{
|
||||
fprintf( stderr, _( "%s: Locale string too long\n"), MIMEDB );
|
||||
error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
for( ; *lang; lang++ )
|
||||
{
|
||||
switch( *lang )
|
||||
|
@ -484,17 +484,17 @@ static char *get_lang_re()
|
|||
*out++ = ')';
|
||||
*out++ = '?';
|
||||
}
|
||||
|
||||
|
||||
close=1;
|
||||
*out++ = '(';
|
||||
*out++ = *lang;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
*out++ = *lang;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( close )
|
||||
{
|
||||
*out++ = ')';
|
||||
|
@ -506,12 +506,12 @@ static char *get_lang_re()
|
|||
}
|
||||
|
||||
/**
|
||||
Get description for a specified mimetype.
|
||||
Get description for a specified mimetype.
|
||||
*/
|
||||
static char *get_description( const char *mimetype )
|
||||
{
|
||||
char *fn_part;
|
||||
|
||||
|
||||
char *fn;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
@ -526,12 +526,12 @@ static char *get_description( const char *mimetype )
|
|||
lang = get_lang_re();
|
||||
if( !lang )
|
||||
return 0;
|
||||
|
||||
|
||||
snprintf( buff, BUFF_SIZE, START_TAG, lang, lang );
|
||||
|
||||
start_re = my_malloc( sizeof(regex_t));
|
||||
stop_re = my_malloc( sizeof(regex_t));
|
||||
|
||||
start_re = (regex_t *)my_malloc( sizeof(regex_t));
|
||||
stop_re = (regex_t *)my_malloc( sizeof(regex_t));
|
||||
|
||||
int reg_status;
|
||||
if( ( reg_status = regcomp( start_re, buff, REG_EXTENDED ) ) )
|
||||
{
|
||||
|
@ -539,7 +539,7 @@ static char *get_description( const char *mimetype )
|
|||
regerror(reg_status, start_re, regerrbuf, BUFF_SIZE);
|
||||
fprintf( stderr, _( "%s: Could not compile regular expressions %s with error %s\n"), MIMEDB, buff, regerrbuf);
|
||||
error=1;
|
||||
|
||||
|
||||
}
|
||||
else if ( ( reg_status = regcomp( stop_re, STOP_TAG, REG_EXTENDED ) ) )
|
||||
{
|
||||
|
@ -547,7 +547,7 @@ static char *get_description( const char *mimetype )
|
|||
regerror(reg_status, stop_re, regerrbuf, BUFF_SIZE);
|
||||
fprintf( stderr, _( "%s: Could not compile regular expressions %s with error %s\n"), MIMEDB, buff, regerrbuf);
|
||||
error=1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
|
@ -559,8 +559,8 @@ static char *get_description( const char *mimetype )
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fn_part = my_malloc( strlen(MIME_DIR) + strlen( mimetype) + strlen(MIME_SUFFIX) + 1 );
|
||||
|
||||
fn_part = (char *)my_malloc( strlen(MIME_DIR) + strlen( mimetype) + strlen(MIME_SUFFIX) + 1 );
|
||||
|
||||
if( !fn_part )
|
||||
{
|
||||
|
@ -573,7 +573,7 @@ static char *get_description( const char *mimetype )
|
|||
|
||||
fn = get_filename(fn_part); //malloc( strlen(MIME_DIR) +strlen( MIME_SUFFIX)+ strlen( mimetype ) + 1 );
|
||||
free(fn_part );
|
||||
|
||||
|
||||
if( !fn )
|
||||
{
|
||||
return 0;
|
||||
|
@ -582,14 +582,14 @@ static char *get_description( const char *mimetype )
|
|||
fd = open( fn, O_RDONLY );
|
||||
|
||||
// fprintf( stderr, "%s\n", fn );
|
||||
|
||||
|
||||
if( fd == -1 )
|
||||
{
|
||||
perror( "open" );
|
||||
error=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( stat( fn, &st) )
|
||||
{
|
||||
perror( "stat" );
|
||||
|
@ -597,12 +597,12 @@ static char *get_description( const char *mimetype )
|
|||
return 0;
|
||||
}
|
||||
|
||||
contents = my_malloc( st.st_size + 1 );
|
||||
contents = (char *)my_malloc( st.st_size + 1 );
|
||||
if( !contents )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( read( fd, contents, st.st_size ) != st.st_size )
|
||||
{
|
||||
perror( "read" );
|
||||
|
@ -619,9 +619,9 @@ static char *get_description( const char *mimetype )
|
|||
contents[st.st_size]=0;
|
||||
regmatch_t match[1];
|
||||
int w = -1;
|
||||
|
||||
|
||||
start=contents;
|
||||
|
||||
|
||||
/*
|
||||
On multiple matches, use the longest match, should be a pretty
|
||||
good heuristic for best match...
|
||||
|
@ -630,10 +630,10 @@ static char *get_description( const char *mimetype )
|
|||
{
|
||||
int new_w = match[0].rm_eo - match[0].rm_so;
|
||||
start += match[0].rm_eo;
|
||||
|
||||
|
||||
if( new_w > w )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
New match is for a longer match then the previous
|
||||
match, so we use the new match
|
||||
*/
|
||||
|
@ -641,7 +641,7 @@ static char *get_description( const char *mimetype )
|
|||
best_start = start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( w != -1 )
|
||||
{
|
||||
start = best_start;
|
||||
|
@ -668,46 +668,46 @@ static char *get_description( const char *mimetype )
|
|||
|
||||
|
||||
/**
|
||||
Get default action for a specified mimetype.
|
||||
Get default action for a specified mimetype.
|
||||
*/
|
||||
static char *get_action( const char *mimetype )
|
||||
{
|
||||
char *res=0;
|
||||
int i;
|
||||
|
||||
|
||||
char *launcher;
|
||||
char *end;
|
||||
array_list_t mime_filenames;
|
||||
|
||||
|
||||
char *launcher_str = NULL;
|
||||
char *launcher_filename, *launcher_command_str, *launcher_command;
|
||||
char *launcher_full;
|
||||
|
||||
|
||||
al_init( &mime_filenames );
|
||||
if( !append_filenames( &mime_filenames, DESKTOP_DEFAULT, 1 ) )
|
||||
{
|
||||
al_destroy( &mime_filenames );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
for ( i = 0; i < al_get_count( &mime_filenames ); i++ )
|
||||
{
|
||||
launcher_str = search_ini( al_get( &mime_filenames, i ), mimetype );
|
||||
launcher_str = (char *)search_ini( (char *)al_get( &mime_filenames, i ), mimetype );
|
||||
if ( launcher_str )
|
||||
break;
|
||||
}
|
||||
|
||||
al_foreach( &mime_filenames, free );
|
||||
al_destroy( &mime_filenames );
|
||||
|
||||
|
||||
if( !launcher_str )
|
||||
{
|
||||
/*
|
||||
This type does not have a launcher. Try the supertype!
|
||||
*/
|
||||
// fprintf( stderr, "mimedb: %s does not have launcher, try supertype\n", mimetype );
|
||||
// fprintf( stderr, "mimedb: %s does not have launcher, try supertype\n", mimetype );
|
||||
const char ** parents = xdg_mime_get_mime_parents(mimetype);
|
||||
|
||||
|
||||
const char **p;
|
||||
if( parents )
|
||||
{
|
||||
|
@ -722,65 +722,65 @@ static char *get_action( const char *mimetype )
|
|||
Just in case subclassing doesn't work, (It doesn't on Fedora
|
||||
Core 3) we also test some common subclassings.
|
||||
*/
|
||||
|
||||
|
||||
if( strncmp( mimetype, "text/plain", 10) != 0 && strncmp( mimetype, "text/", 5 ) == 0 )
|
||||
return get_action( "text/plain" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fprintf( stderr, "WOOT %s\n", launcher_str );
|
||||
|
||||
// fprintf( stderr, "WOOT %s\n", launcher_str );
|
||||
launcher = strchr( launcher_str, '=' );
|
||||
|
||||
|
||||
if( !launcher )
|
||||
{
|
||||
fprintf( stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str );
|
||||
fprintf( stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str );
|
||||
error=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Skip the = */
|
||||
launcher++;
|
||||
|
||||
|
||||
/* Only use first launcher */
|
||||
end = strchr( launcher, ';' );
|
||||
if( end )
|
||||
*end = '\0';
|
||||
|
||||
launcher_full = my_malloc( strlen( launcher) + strlen( APPLICATIONS_DIR)+1 );
|
||||
launcher_full = (char *)my_malloc( strlen( launcher) + strlen( APPLICATIONS_DIR)+1 );
|
||||
if( !launcher_full )
|
||||
{
|
||||
free( launcher_str );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
strcpy( launcher_full, APPLICATIONS_DIR );
|
||||
strcat( launcher_full, launcher );
|
||||
free( launcher_str );
|
||||
|
||||
|
||||
launcher_filename = get_filename( launcher_full );
|
||||
|
||||
|
||||
free( launcher_full );
|
||||
|
||||
|
||||
launcher_command_str = search_ini( launcher_filename, "Exec" );
|
||||
|
||||
|
||||
if( !launcher_command_str )
|
||||
{
|
||||
fprintf( stderr,
|
||||
_( "%s: Default launcher '%s' does not specify how to start\n"), MIMEDB,
|
||||
fprintf( stderr,
|
||||
_( "%s: Default launcher '%s' does not specify how to start\n"), MIMEDB,
|
||||
launcher_filename );
|
||||
free( launcher_filename );
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
free( launcher_filename );
|
||||
|
||||
|
||||
launcher_command = strchr( launcher_command_str, '=' );
|
||||
launcher_command++;
|
||||
|
||||
|
||||
res = my_strdup( launcher_command );
|
||||
|
||||
free( launcher_command_str );
|
||||
|
||||
free( launcher_command_str );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -793,11 +793,11 @@ static void writer( char c )
|
|||
{
|
||||
if( launch_len == -1 )
|
||||
return;
|
||||
|
||||
|
||||
if( launch_len <= launch_pos )
|
||||
{
|
||||
int new_len = launch_len?2*launch_len:256;
|
||||
char *new_buff = realloc( launch_buff, new_len );
|
||||
char *new_buff = (char *)realloc( launch_buff, new_len );
|
||||
if( !new_buff )
|
||||
{
|
||||
free( launch_buff );
|
||||
|
@ -807,7 +807,7 @@ static void writer( char c )
|
|||
}
|
||||
launch_buff = new_buff;
|
||||
launch_len = new_len;
|
||||
|
||||
|
||||
}
|
||||
launch_buff[launch_pos++]=c;
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ static void writer_hex( int num )
|
|||
*/
|
||||
static char *my_getcwd ()
|
||||
{
|
||||
size_t size = 100;
|
||||
size_t size = 100;
|
||||
while (1)
|
||||
{
|
||||
char *buffer = (char *) malloc (size);
|
||||
|
@ -849,7 +849,7 @@ static char *my_getcwd ()
|
|||
static char *get_fullfile( char *file )
|
||||
{
|
||||
char *fullfile;
|
||||
|
||||
|
||||
if( file[0] == '/' )
|
||||
{
|
||||
fullfile = file;
|
||||
|
@ -863,10 +863,10 @@ static char *get_fullfile( char *file )
|
|||
perror( "getcwd" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int l = strlen(cwd);
|
||||
|
||||
fullfile = my_malloc( l + strlen(file)+2 );
|
||||
|
||||
fullfile = (char *)my_malloc( l + strlen(file)+2 );
|
||||
if( !fullfile )
|
||||
{
|
||||
free(cwd);
|
||||
|
@ -876,7 +876,7 @@ static char *get_fullfile( char *file )
|
|||
if( cwd[l-1] != '/' )
|
||||
strcat(fullfile, "/" );
|
||||
strcat( fullfile, file );
|
||||
|
||||
|
||||
free(cwd);
|
||||
}
|
||||
return fullfile;
|
||||
|
@ -890,13 +890,13 @@ static void write_url( char *file )
|
|||
{
|
||||
char *fullfile = get_fullfile( file );
|
||||
char *str = fullfile;
|
||||
|
||||
|
||||
if( str == 0 )
|
||||
{
|
||||
launch_len = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
writer( 'f');
|
||||
writer( 'i');
|
||||
writer( 'l');
|
||||
|
@ -911,9 +911,9 @@ static void write_url( char *file )
|
|||
((*str >= '0') && (*str <='9')) ||
|
||||
(strchr( "-_.~/",*str) != 0) )
|
||||
{
|
||||
writer(*str);
|
||||
writer(*str);
|
||||
}
|
||||
else if(strchr( "()?&=",*str) != 0)
|
||||
else if(strchr( "()?&=",*str) != 0)
|
||||
{
|
||||
writer('\\');
|
||||
writer(*str);
|
||||
|
@ -927,7 +927,7 @@ static void write_url( char *file )
|
|||
}
|
||||
if( fullfile != file )
|
||||
free( fullfile );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -951,7 +951,7 @@ static void write_file( char *file, int print_path )
|
|||
}
|
||||
str = basename( fullfile );
|
||||
}
|
||||
|
||||
|
||||
if( !str )
|
||||
{
|
||||
error = 1;
|
||||
|
@ -1024,7 +1024,7 @@ static void write_file( char *file, int print_path )
|
|||
}
|
||||
|
||||
/**
|
||||
Use the specified launch filter to launch all the files in the specified list.
|
||||
Use the specified launch filter to launch all the files in the specified list.
|
||||
|
||||
\param filter the action to take
|
||||
\param files the list of files for which to perform the action
|
||||
|
@ -1035,11 +1035,11 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
char *filter_org=filter;
|
||||
int count=0;
|
||||
int launch_again=0;
|
||||
|
||||
|
||||
if( al_get_count( files ) <= fileno )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
launch_pos=0;
|
||||
|
||||
for( ;*filter && !error; filter++)
|
||||
|
@ -1054,7 +1054,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
launch_again = 1;
|
||||
write_url( (char *)al_get( files, fileno ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 'U':
|
||||
{
|
||||
int i;
|
||||
|
@ -1066,10 +1066,10 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
if( error )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'f':
|
||||
case 'n':
|
||||
{
|
||||
|
@ -1077,7 +1077,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
write_file( (char *)al_get( files, fileno ), *filter == 'f' );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'F':
|
||||
case 'N':
|
||||
{
|
||||
|
@ -1092,14 +1092,14 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case 'd':
|
||||
{
|
||||
char *cpy = get_fullfile( (char *)al_get( files, fileno ) );
|
||||
char *dir;
|
||||
|
||||
launch_again=1;
|
||||
launch_again=1;
|
||||
/*
|
||||
We wish to modify this string, make sure it is only a copy
|
||||
*/
|
||||
|
@ -1113,16 +1113,16 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
dir=dirname( cpy );
|
||||
write_file( dir, 1 );
|
||||
free( cpy );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'D':
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( files ); i++ )
|
||||
{
|
||||
char *cpy = get_fullfile( (char *)al_get( files, i ) );
|
||||
char *cpy = get_fullfile( (char *)al_get( files, i ) );
|
||||
char *dir;
|
||||
|
||||
/*
|
||||
|
@ -1136,7 +1136,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
break;
|
||||
}
|
||||
dir=dirname( cpy );
|
||||
|
||||
|
||||
if( i != 0 )
|
||||
writer( ' ' );
|
||||
|
||||
|
@ -1144,14 +1144,14 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
free( cpy );
|
||||
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
fprintf( stderr, _("%s: Unsupported switch '%c' in launch string '%s'\n"), MIMEDB, *filter, filter_org );
|
||||
launch_len=0;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1163,7 +1163,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
|
||||
if( error )
|
||||
return;
|
||||
|
||||
|
||||
switch( launch_len )
|
||||
{
|
||||
case -1:
|
||||
|
@ -1178,17 +1178,17 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
}
|
||||
default:
|
||||
{
|
||||
|
||||
|
||||
writer( ' ' );
|
||||
writer( '&' );
|
||||
writer( '\0' );
|
||||
|
||||
|
||||
if( system( launch_buff ) == -1 )
|
||||
{
|
||||
fprintf( stderr, _( ERROR_SYSTEM ), MIMEDB, launch_buff );
|
||||
exit(STATUS_ERROR_SYSTEM);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1196,7 +1196,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
{
|
||||
launch( filter_org, files, fileno+1 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1233,19 +1233,19 @@ static void locale_init()
|
|||
Main function. Parses options and calls helper function for any heavy lifting.
|
||||
*/
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
int input_type=FILEDATA;
|
||||
int output_type=MIMETYPE;
|
||||
|
||||
|
||||
const char *mimetype;
|
||||
char *output=0;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
hash_table_t launch_hash;
|
||||
|
||||
locale_init();
|
||||
|
||||
|
||||
/*
|
||||
Parse options
|
||||
*/
|
||||
|
@ -1255,103 +1255,103 @@ int main (int argc, char *argv[])
|
|||
long_options[] =
|
||||
{
|
||||
{
|
||||
"input-file-data", no_argument, 0, 't'
|
||||
"input-file-data", no_argument, 0, 't'
|
||||
}
|
||||
,
|
||||
{
|
||||
"input-filename", no_argument, 0, 'f'
|
||||
"input-filename", no_argument, 0, 'f'
|
||||
}
|
||||
,
|
||||
{
|
||||
"input-mime", no_argument, 0, 'i'
|
||||
"input-mime", no_argument, 0, 'i'
|
||||
}
|
||||
,
|
||||
{
|
||||
"output-mime", no_argument, 0, 'm'
|
||||
"output-mime", no_argument, 0, 'm'
|
||||
}
|
||||
,
|
||||
{
|
||||
"output-description", no_argument, 0, 'd'
|
||||
"output-description", no_argument, 0, 'd'
|
||||
}
|
||||
,
|
||||
{
|
||||
"output-action", no_argument, 0, 'a'
|
||||
"output-action", no_argument, 0, 'a'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
"launch", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 't':
|
||||
input_type=FILEDATA;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'f':
|
||||
input_type=FILENAME;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'i':
|
||||
input_type=MIMETYPE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'm':
|
||||
output_type=MIMETYPE;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'd':
|
||||
output_type=DESCRIPTION;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'a':
|
||||
output_type=ACTION;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'l':
|
||||
output_type=LAUNCH;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
printf( _("%s, version %s\n"), MIMEDB, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
exit( 0 );
|
||||
|
||||
case '?':
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( ( output_type == LAUNCH )&&(input_type==MIMETYPE))
|
||||
|
@ -1363,13 +1363,13 @@ int main (int argc, char *argv[])
|
|||
|
||||
if( output_type == LAUNCH )
|
||||
hash_init( &launch_hash, &hash_str_func, &hash_str_cmp );
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
/*
|
||||
Loop over all non option arguments and do the specified lookup
|
||||
*/
|
||||
|
||||
//fprintf( stderr, "Input %d, output %d\n", input_type, output_type );
|
||||
|
||||
//fprintf( stderr, "Input %d, output %d\n", input_type, output_type );
|
||||
|
||||
for (i = optind; (i < argc)&&(!error); i++)
|
||||
{
|
||||
|
@ -1392,7 +1392,7 @@ int main (int argc, char *argv[])
|
|||
error=1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert from mimetype to whatever, if needed
|
||||
*/
|
||||
|
@ -1402,21 +1402,21 @@ int main (int argc, char *argv[])
|
|||
{
|
||||
output = (char *)mimetype;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
case DESCRIPTION:
|
||||
{
|
||||
output = get_description( mimetype );
|
||||
output = get_description( mimetype );
|
||||
if( !output )
|
||||
output = strdup( _("Unknown") );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION:
|
||||
{
|
||||
output = get_action( mimetype );
|
||||
break;
|
||||
}
|
||||
}
|
||||
case LAUNCH:
|
||||
{
|
||||
/*
|
||||
|
@ -1427,10 +1427,10 @@ int main (int argc, char *argv[])
|
|||
*/
|
||||
array_list_t *l= (array_list_t *)hash_get( &launch_hash, mimetype );
|
||||
output = 0;
|
||||
|
||||
|
||||
if( !l )
|
||||
{
|
||||
l = my_malloc( sizeof( array_list_t ) );
|
||||
l = (array_list_t *)my_malloc( sizeof( array_list_t ) );
|
||||
if( l == 0 )
|
||||
{
|
||||
break;
|
||||
|
@ -1438,10 +1438,10 @@ int main (int argc, char *argv[])
|
|||
al_init( l );
|
||||
hash_put( &launch_hash, mimetype, l );
|
||||
}
|
||||
al_push( l, argv[i] );
|
||||
al_push( l, argv[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Print the glorious result
|
||||
*/
|
||||
|
@ -1471,9 +1471,9 @@ int main (int argc, char *argv[])
|
|||
{
|
||||
fprintf( stderr, _( "%s: Unknown error\n"), MIMEDB );
|
||||
error=1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
char *launcher = get_action( mimetype );
|
||||
|
||||
if( launcher )
|
||||
|
@ -1486,7 +1486,7 @@ int main (int argc, char *argv[])
|
|||
hash_destroy( &launch_hash );
|
||||
al_destroy( &mimes );
|
||||
}
|
||||
|
||||
|
||||
if( launch_buff )
|
||||
free( launch_buff );
|
||||
|
||||
|
@ -1496,9 +1496,9 @@ int main (int argc, char *argv[])
|
|||
regfree( stop_re );
|
||||
free( start_re );
|
||||
free( stop_re );
|
||||
}
|
||||
}
|
||||
|
||||
xdg_mime_shutdown();
|
||||
|
||||
return error;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
68
output.cpp
68
output.cpp
|
@ -65,7 +65,7 @@
|
|||
static int writeb_internal( char c );
|
||||
|
||||
/**
|
||||
Names of different colors.
|
||||
Names of different colors.
|
||||
*/
|
||||
static wchar_t *col[]=
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ static wchar_t *col[]=
|
|||
*/
|
||||
static int col_idx[]=
|
||||
{
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
|
@ -108,7 +108,7 @@ static int col_idx[]=
|
|||
/**
|
||||
Size of writestr_buff
|
||||
*/
|
||||
static size_t writestr_buff_sz=0;
|
||||
static size_t writestr_buff_sz=0;
|
||||
|
||||
/**
|
||||
Temp buffer used for converting from wide to narrow strings
|
||||
|
@ -167,7 +167,7 @@ void set_color( int c, int c2 )
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
is_bold |= (c&FISH_COLOR_BOLD)!=0;
|
||||
is_bold |= (c2&FISH_COLOR_BOLD)!=0;
|
||||
|
@ -210,7 +210,7 @@ void set_color( int c, int c2 )
|
|||
if( was_bold && !is_bold )
|
||||
{
|
||||
/*
|
||||
Only way to exit bold mode is a reset of all attributes.
|
||||
Only way to exit bold mode is a reset of all attributes.
|
||||
*/
|
||||
writembs( exit_attribute_mode );
|
||||
last_color = FISH_COLOR_NORMAL;
|
||||
|
@ -218,7 +218,7 @@ void set_color( int c, int c2 )
|
|||
was_bold=0;
|
||||
was_underline=0;
|
||||
}
|
||||
|
||||
|
||||
if( last_color2 != FISH_COLOR_NORMAL &&
|
||||
last_color2 != FISH_COLOR_RESET &&
|
||||
last_color2 != FISH_COLOR_IGNORE )
|
||||
|
@ -313,7 +313,7 @@ void set_color( int c, int c2 )
|
|||
writembs( tparm( fg, last_color ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
was_bold=0;
|
||||
was_underline=0;
|
||||
|
@ -341,20 +341,20 @@ void set_color( int c, int c2 )
|
|||
writembs( tparm( enter_bold_mode ) );
|
||||
}
|
||||
}
|
||||
was_bold = is_bold;
|
||||
was_bold = is_bold;
|
||||
}
|
||||
|
||||
if( was_underline && !is_underline )
|
||||
{
|
||||
writembs( exit_underline_mode );
|
||||
writembs( exit_underline_mode );
|
||||
}
|
||||
|
||||
|
||||
if( !was_underline && is_underline )
|
||||
{
|
||||
writembs( enter_underline_mode );
|
||||
writembs( enter_underline_mode );
|
||||
}
|
||||
was_underline = is_underline;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,7 +375,7 @@ int writeb( tputs_arg_t b )
|
|||
int writembs_internal( char *str )
|
||||
{
|
||||
CHECK( str, 1 );
|
||||
|
||||
|
||||
return tputs(str,1,&writeb)==ERR?1:0;
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ int writech( wint_t ch )
|
|||
{
|
||||
memset( &state, 0, sizeof(state) );
|
||||
bytes= wcrtomb( buff, ch, &state );
|
||||
|
||||
|
||||
switch( bytes )
|
||||
{
|
||||
case (size_t)(-1):
|
||||
|
@ -405,7 +405,7 @@ int writech( wint_t ch )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<bytes; i++ )
|
||||
{
|
||||
out( buff[i] );
|
||||
|
@ -418,7 +418,7 @@ void writestr( const wchar_t *str )
|
|||
char *pos;
|
||||
|
||||
CHECK( str, );
|
||||
|
||||
|
||||
// while( *str )
|
||||
// writech( *str++ );
|
||||
|
||||
|
@ -426,15 +426,15 @@ void writestr( const wchar_t *str )
|
|||
Check amount of needed space
|
||||
*/
|
||||
size_t len = wcstombs( 0, str, 0 );
|
||||
|
||||
|
||||
if( len == (size_t)-1 )
|
||||
{
|
||||
debug( 1, L"Tried to print invalid wide character string" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
len++;
|
||||
|
||||
|
||||
/*
|
||||
Reallocate if needed
|
||||
*/
|
||||
|
@ -444,19 +444,19 @@ void writestr( const wchar_t *str )
|
|||
{
|
||||
halloc_register_function_void( global_context, &output_destroy );
|
||||
}
|
||||
|
||||
writestr_buff = realloc( writestr_buff, len );
|
||||
|
||||
writestr_buff = (char *)realloc( writestr_buff, len );
|
||||
if( !writestr_buff )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
writestr_buff_sz = len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert
|
||||
*/
|
||||
wcstombs( writestr_buff,
|
||||
wcstombs( writestr_buff,
|
||||
str,
|
||||
writestr_buff_sz );
|
||||
|
||||
|
@ -476,7 +476,7 @@ void writestr_ellipsis( const wchar_t *str, int max_width )
|
|||
int tot;
|
||||
|
||||
CHECK( str, );
|
||||
|
||||
|
||||
tot = my_wcswidth(str);
|
||||
|
||||
if( tot <= max_width )
|
||||
|
@ -515,7 +515,7 @@ int write_escaped_str( const wchar_t *str, int max_len )
|
|||
int written=0;
|
||||
|
||||
CHECK( str, 0 );
|
||||
|
||||
|
||||
out = escape( str, 1 );
|
||||
len = my_wcswidth( out );
|
||||
|
||||
|
@ -528,7 +528,7 @@ int write_escaped_str( const wchar_t *str, int max_len )
|
|||
}
|
||||
writech( ellipsis_char );
|
||||
written += wcwidth( ellipsis_char );
|
||||
|
||||
|
||||
for( i=written; i<max_len; i++ )
|
||||
{
|
||||
writech( L' ' );
|
||||
|
@ -552,17 +552,17 @@ int output_color_code( const wchar_t *val )
|
|||
array_list_t el;
|
||||
int is_bold=0;
|
||||
int is_underline=0;
|
||||
|
||||
|
||||
if( !val )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
|
||||
al_init( &el );
|
||||
tokenize_variable_array( val, &el );
|
||||
|
||||
|
||||
for( j=0; j<al_get_count( &el ); j++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &el, j );
|
||||
|
||||
|
||||
is_bold |= (wcsncmp( next, L"--bold", wcslen(next) ) == 0 ) && wcslen(next)>=3;
|
||||
is_bold |= wcscmp( next, L"-o" ) == 0;
|
||||
|
||||
|
@ -577,14 +577,14 @@ int output_color_code( const wchar_t *val )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
al_foreach( &el, &free );
|
||||
al_destroy( &el );
|
||||
|
||||
return color | (is_bold?FISH_COLOR_BOLD:0) | (is_underline?FISH_COLOR_UNDERLINE:0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void output_set_term( wchar_t *term )
|
||||
|
@ -594,7 +594,7 @@ void output_set_term( wchar_t *term )
|
|||
|
||||
wchar_t *output_get_term()
|
||||
{
|
||||
return current_term ? current_term : L"<unknown>";
|
||||
return (wchar_t *)(current_term ? current_term : L"<unknown>");
|
||||
}
|
||||
|
||||
|
||||
|
|
2
output.h
2
output.h
|
@ -11,7 +11,7 @@
|
|||
#include <wchar.h>
|
||||
|
||||
/**
|
||||
Constants for various colors as used by the set_color function.
|
||||
Constants for various colors as used by the set_color function.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
|
|
262
parse_util.cpp
262
parse_util.cpp
|
@ -5,7 +5,7 @@
|
|||
|
||||
This library can be seen as a 'toolbox' for functions that are
|
||||
used in many places in fish and that are somehow related to
|
||||
parsing the code.
|
||||
parsing the code.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -108,7 +108,7 @@ int parse_util_lineno( const wchar_t *str, int len )
|
|||
prev_str = prev_str2;
|
||||
i=i2;
|
||||
res=res2;
|
||||
|
||||
|
||||
prev_str2 = tmp_str;
|
||||
i2 = tmp_i;
|
||||
res2 = tmp_res;
|
||||
|
@ -118,13 +118,13 @@ int parse_util_lineno( const wchar_t *str, int len )
|
|||
prev_str2 = prev_str;
|
||||
i2 = i;
|
||||
res2=res;
|
||||
|
||||
|
||||
prev_str = (wchar_t *)str;
|
||||
i=0;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( ; str[i] && i<len; i++ )
|
||||
{
|
||||
if( str[i] == L'\n' )
|
||||
|
@ -146,14 +146,14 @@ int parse_util_get_line_from_offset( wchar_t *buff, int pos )
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<pos; i++ )
|
||||
{
|
||||
if( !buff[i] )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( buff[i] == L'\n' )
|
||||
{
|
||||
count++;
|
||||
|
@ -167,7 +167,7 @@ int parse_util_get_offset_from_line( wchar_t *buff, int line )
|
|||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
|
||||
if( line < 0 )
|
||||
{
|
||||
return -1;
|
||||
|
@ -175,14 +175,14 @@ int parse_util_get_offset_from_line( wchar_t *buff, int line )
|
|||
|
||||
if( line == 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
for( i=0;; i++ )
|
||||
{
|
||||
if( !buff[i] )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( buff[i] == L'\n' )
|
||||
{
|
||||
count++;
|
||||
|
@ -190,7 +190,7 @@ int parse_util_get_offset_from_line( wchar_t *buff, int line )
|
|||
{
|
||||
return i+1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,46 +200,46 @@ int parse_util_get_offset( wchar_t *buff, int line, int line_offset )
|
|||
int off = parse_util_get_offset_from_line( buff, line );
|
||||
int off2 = parse_util_get_offset_from_line( buff, line+1 );
|
||||
int line_offset2 = line_offset;
|
||||
|
||||
|
||||
if( off < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( off2 < 0 )
|
||||
{
|
||||
off2 = wcslen( buff )+1;
|
||||
}
|
||||
|
||||
|
||||
if( line_offset2 < 0 )
|
||||
{
|
||||
line_offset2 = 0;
|
||||
}
|
||||
|
||||
|
||||
if( line_offset2 >= off2-off-1 )
|
||||
{
|
||||
line_offset2 = off2-off-1;
|
||||
}
|
||||
|
||||
|
||||
return off + line_offset2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
wchar_t **begin,
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
wchar_t **begin,
|
||||
wchar_t **end,
|
||||
int allow_incomplete )
|
||||
{
|
||||
wchar_t *pos;
|
||||
wchar_t prev=0;
|
||||
int syntax_error=0;
|
||||
int paran_count=0;
|
||||
int paran_count=0;
|
||||
|
||||
wchar_t *paran_begin=0, *paran_end=0;
|
||||
|
||||
CHECK( in, 0 );
|
||||
|
||||
|
||||
for( pos = (wchar_t *)in; *pos; pos++ )
|
||||
{
|
||||
if( prev != '\\' )
|
||||
|
@ -264,7 +264,7 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
|||
{
|
||||
paran_begin = pos;
|
||||
}
|
||||
|
||||
|
||||
paran_count++;
|
||||
}
|
||||
else if( *pos == ')' )
|
||||
|
@ -277,7 +277,7 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
|||
paran_end = pos;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( paran_count < 0 )
|
||||
{
|
||||
syntax_error = 1;
|
||||
|
@ -285,19 +285,19 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
prev = *pos;
|
||||
}
|
||||
|
||||
|
||||
syntax_error |= (paran_count < 0 );
|
||||
syntax_error |= ((paran_count>0)&&(!allow_incomplete));
|
||||
|
||||
|
||||
if( syntax_error )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( paran_begin == 0 )
|
||||
{
|
||||
return 0;
|
||||
|
@ -312,20 +312,20 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
|||
{
|
||||
*end = paran_count?(wchar_t *)in+wcslen(in):paran_end;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b )
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
wchar_t *pos;
|
||||
const wchar_t *cursor = buff + cursor_pos;
|
||||
|
||||
|
||||
CHECK( buff, );
|
||||
|
||||
if( a )
|
||||
|
@ -337,9 +337,9 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
|||
{
|
||||
*b = (wchar_t *)buff+wcslen(buff);
|
||||
}
|
||||
|
||||
|
||||
pos = (wchar_t *)buff;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( parse_util_locate_cmdsubst( pos,
|
||||
|
@ -379,10 +379,10 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
|||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
pos = end+1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -390,19 +390,19 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
|||
*/
|
||||
static void job_or_process_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
wchar_t **a,
|
||||
wchar_t **b,
|
||||
wchar_t **a,
|
||||
wchar_t **b,
|
||||
int process )
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
int pos;
|
||||
wchar_t *buffcpy;
|
||||
int finished=0;
|
||||
|
||||
|
||||
tokenizer tok;
|
||||
|
||||
CHECK( buff, );
|
||||
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a=0;
|
||||
|
@ -412,20 +412,20 @@ static void job_or_process_extent( const wchar_t *buff,
|
|||
{
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
if( !end || !begin )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a = begin;
|
||||
}
|
||||
|
||||
|
||||
if( b )
|
||||
{
|
||||
*b = end;
|
||||
|
@ -453,14 +453,14 @@ static void job_or_process_extent( const wchar_t *buff,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case TOK_END:
|
||||
case TOK_BACKGROUND:
|
||||
{
|
||||
|
||||
|
||||
if( tok_begin >= pos )
|
||||
{
|
||||
finished=1;
|
||||
finished=1;
|
||||
if( b )
|
||||
{
|
||||
*b = (wchar_t *)buff + tok_begin;
|
||||
|
@ -474,31 +474,31 @@ static void job_or_process_extent( const wchar_t *buff,
|
|||
}
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free( buffcpy);
|
||||
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
}
|
||||
|
||||
void parse_util_process_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b )
|
||||
{
|
||||
job_or_process_extent( buff, pos, a, b, 1 );
|
||||
job_or_process_extent( buff, pos, a, b, 1 );
|
||||
}
|
||||
|
||||
void parse_util_job_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b )
|
||||
{
|
||||
job_or_process_extent( buff,pos,a, b, 0 );
|
||||
job_or_process_extent( buff,pos,a, b, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -506,7 +506,7 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
int cursor_pos,
|
||||
wchar_t **tok_begin,
|
||||
wchar_t **tok_end,
|
||||
wchar_t **prev_begin,
|
||||
wchar_t **prev_begin,
|
||||
wchar_t **prev_end )
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
|
@ -516,34 +516,34 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
tokenizer tok;
|
||||
|
||||
wchar_t *a, *b, *pa, *pb;
|
||||
|
||||
|
||||
CHECK( buff, );
|
||||
|
||||
|
||||
assert( cursor_pos >= 0 );
|
||||
|
||||
a = b = pa = pb = 0;
|
||||
|
||||
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
|
||||
if( !end || !begin )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
|
||||
|
||||
a = (wchar_t *)buff + pos;
|
||||
b = a;
|
||||
pa = (wchar_t *)buff + pos;
|
||||
pb = pa;
|
||||
|
||||
|
||||
assert( begin >= buff );
|
||||
assert( begin <= (buff+wcslen(buff) ) );
|
||||
assert( end >= begin );
|
||||
assert( end <= (buff+wcslen(buff) ) );
|
||||
|
||||
|
||||
buffcpy = wcsndup( begin, end-begin );
|
||||
|
||||
|
||||
if( !buffcpy )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
@ -563,7 +563,7 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
{
|
||||
tok_end +=wcslen(tok_last(&tok));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cursor was before beginning of this token, means that the
|
||||
cursor is between two tokens, so we set it to a zero element
|
||||
|
@ -580,12 +580,12 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
looking for. If so, set a and b and break
|
||||
*/
|
||||
if( (tok_last_type( &tok ) == TOK_STRING) && (tok_end >= pos ) )
|
||||
{
|
||||
{
|
||||
a = begin + tok_get_pos( &tok );
|
||||
b = a + wcslen(tok_last(&tok));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Remember previous string token
|
||||
*/
|
||||
|
@ -597,7 +597,7 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
}
|
||||
|
||||
free( buffcpy);
|
||||
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
if( tok_begin )
|
||||
|
@ -619,7 +619,7 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
{
|
||||
*prev_end = pb;
|
||||
}
|
||||
|
||||
|
||||
assert( pa >= buff );
|
||||
assert( pa <= (buff+wcslen(buff) ) );
|
||||
assert( pb >= pa );
|
||||
|
@ -648,14 +648,14 @@ static void clear_hash_value( void *key, void *data, void *aux )
|
|||
handler( name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
/**
|
||||
Part of the autoloader cleanup
|
||||
Part of the autoloader cleanup
|
||||
*/
|
||||
static void clear_loaded_entry( void *key,
|
||||
static void clear_loaded_entry( void *key,
|
||||
void *data,
|
||||
void *handler )
|
||||
{
|
||||
|
@ -667,7 +667,7 @@ static void clear_loaded_entry( void *key,
|
|||
hash_destroy( &loaded->is_loading );
|
||||
|
||||
free( loaded->old_path );
|
||||
free( loaded );
|
||||
free( loaded );
|
||||
free( (void *)key );
|
||||
}
|
||||
|
||||
|
@ -683,9 +683,9 @@ static void parse_util_destroy()
|
|||
hash_foreach2( all_loaded,
|
||||
&clear_loaded_entry,
|
||||
0 );
|
||||
|
||||
|
||||
hash_destroy( all_loaded );
|
||||
free( all_loaded );
|
||||
free( all_loaded );
|
||||
all_loaded = 0;
|
||||
}
|
||||
}
|
||||
|
@ -704,7 +704,7 @@ void parse_util_load_reset( const wchar_t *path_var_name,
|
|||
clear_loaded_entry( key, data, (void *)on_load );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int parse_util_unload( const wchar_t *cmd,
|
||||
|
@ -721,14 +721,14 @@ int parse_util_unload( const wchar_t *cmd,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
loaded = (autoload_t *)hash_get( all_loaded, path_var_name );
|
||||
|
||||
|
||||
if( !loaded )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
hash_remove( &loaded->load_time, cmd, 0, &val );
|
||||
if( val )
|
||||
{
|
||||
|
@ -738,7 +738,7 @@ int parse_util_unload( const wchar_t *cmd,
|
|||
}
|
||||
free( val );
|
||||
}
|
||||
|
||||
|
||||
return !!val;
|
||||
}
|
||||
|
||||
|
@ -763,13 +763,13 @@ static void parse_util_autounload( const wchar_t *path_var_name,
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
loaded = (autoload_t *)hash_get( all_loaded, path_var_name );
|
||||
if( !loaded )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( hash_get_count( &loaded->load_time ) >= AUTOLOAD_MAX )
|
||||
{
|
||||
time_t oldest_access = time(0) - AUTOLOAD_MIN_AGE;
|
||||
|
@ -781,25 +781,25 @@ static void parse_util_autounload( const wchar_t *path_var_name,
|
|||
for( i=0; i<al_get_count( &key ); i++ )
|
||||
{
|
||||
wchar_t *item = (wchar_t *)al_get( &key, i );
|
||||
time_t *tm = hash_get( &loaded->load_time, item );
|
||||
time_t *tm = (time_t *)hash_get( &loaded->load_time, item );
|
||||
|
||||
if( wcscmp( item, skip ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( !tm[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( hash_get( &loaded->is_loading, item ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
loaded_count++;
|
||||
|
||||
|
||||
if( tm[1] < oldest_access )
|
||||
{
|
||||
oldest_access = tm[1];
|
||||
|
@ -807,7 +807,7 @@ static void parse_util_autounload( const wchar_t *path_var_name,
|
|||
}
|
||||
}
|
||||
al_destroy( &key );
|
||||
|
||||
|
||||
if( oldest_item && loaded_count > AUTOLOAD_MAX)
|
||||
{
|
||||
parse_util_unload( oldest_item, path_var_name, on_load );
|
||||
|
@ -835,17 +835,17 @@ int parse_util_load( const wchar_t *cmd,
|
|||
|
||||
int res;
|
||||
int c, c2;
|
||||
|
||||
|
||||
CHECK( path_var_name, 0 );
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
CHECK_BLOCK( 0 );
|
||||
|
||||
|
||||
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
|
||||
|
||||
parse_util_autounload( path_var_name, cmd, on_load );
|
||||
path_var = env_get( path_var_name );
|
||||
|
||||
path_var = env_get( path_var_name );
|
||||
|
||||
/*
|
||||
Do we know where to look?
|
||||
*/
|
||||
|
@ -859,7 +859,7 @@ int parse_util_load( const wchar_t *cmd,
|
|||
*/
|
||||
if( !all_loaded )
|
||||
{
|
||||
all_loaded = malloc( sizeof( hash_table_t ) );
|
||||
all_loaded = (hash_table_t *)malloc( sizeof( hash_table_t ) );
|
||||
halloc_register_function_void( global_context, &parse_util_destroy );
|
||||
if( !all_loaded )
|
||||
{
|
||||
|
@ -867,7 +867,7 @@ int parse_util_load( const wchar_t *cmd,
|
|||
}
|
||||
hash_init( all_loaded, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
|
||||
loaded = (autoload_t *)hash_get( all_loaded, path_var_name );
|
||||
|
||||
if( loaded )
|
||||
|
@ -888,13 +888,13 @@ int parse_util_load( const wchar_t *cmd,
|
|||
*/
|
||||
if( hash_get( &loaded->is_loading, cmd ) )
|
||||
{
|
||||
debug( 0,
|
||||
_( L"Could not autoload item '%ls', it is already being autoloaded. "
|
||||
L"This is a circular dependency in the autoloading scripts, please remove it."),
|
||||
debug( 0,
|
||||
_( L"Could not autoload item '%ls', it is already being autoloaded. "
|
||||
L"This is a circular dependency in the autoloading scripts, please remove it."),
|
||||
cmd );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -904,26 +904,26 @@ int parse_util_load( const wchar_t *cmd,
|
|||
set up initial data
|
||||
*/
|
||||
// debug( 0, L"Create brand new autoload_t for %ls->%ls", path_var_name, path_var );
|
||||
loaded = malloc( sizeof( autoload_t ) );
|
||||
loaded = (autoload_t *)malloc( sizeof( autoload_t ) );
|
||||
if( !loaded )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
hash_init( &loaded->load_time, &hash_wcs_func, &hash_wcs_cmp );
|
||||
hash_put( all_loaded, wcsdup(path_var_name), loaded );
|
||||
|
||||
|
||||
hash_init( &loaded->is_loading, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
loaded->old_path = wcsdup( path_var );
|
||||
}
|
||||
|
||||
|
||||
path_list = al_new( global_context);
|
||||
|
||||
path_list = (array_list_t *)al_new();
|
||||
|
||||
tokenize_variable_array( path_var, path_list );
|
||||
|
||||
|
||||
c = al_get_count( path_list );
|
||||
|
||||
|
||||
hash_put( &loaded->is_loading, cmd, cmd );
|
||||
|
||||
/*
|
||||
|
@ -940,7 +940,7 @@ int parse_util_load( const wchar_t *cmd,
|
|||
*/
|
||||
hash_remove( &loaded->is_loading, cmd, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
c2 = al_get_count( path_list );
|
||||
|
||||
al_foreach( path_list, &free );
|
||||
|
@ -950,9 +950,9 @@ int parse_util_load( const wchar_t *cmd,
|
|||
/**
|
||||
Make sure we didn't 'drop' something
|
||||
*/
|
||||
|
||||
|
||||
assert( c == c2 );
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -977,7 +977,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
Get modification time of file
|
||||
*/
|
||||
tm = (time_t *)hash_get( &loaded->load_time, cmd );
|
||||
|
||||
|
||||
/*
|
||||
Did we just check this?
|
||||
*/
|
||||
|
@ -988,7 +988,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return if already loaded and we are skipping reloading
|
||||
*/
|
||||
|
@ -996,7 +996,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( !path )
|
||||
{
|
||||
path = sb_halloc( global_context );
|
||||
|
@ -1005,7 +1005,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
{
|
||||
sb_clear( path );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Iterate over path searching for suitable completion files
|
||||
*/
|
||||
|
@ -1014,7 +1014,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
struct stat buf;
|
||||
wchar_t *next = (wchar_t *)al_get( path_list, i );
|
||||
sb_clear( path );
|
||||
sb_append( path, next, L"/", cmd, L".fish", (void *)0 );
|
||||
sb_append( path, next, L"/", cmd, L".fish", NULL );
|
||||
|
||||
if( (wstat( (wchar_t *)path->buff, &buf )== 0) &&
|
||||
(waccess( (wchar_t *)path->buff, R_OK ) == 0) )
|
||||
|
@ -1024,10 +1024,10 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
wchar_t *esc = escape( (wchar_t *)path->buff, 1 );
|
||||
wchar_t *src_cmd = wcsdupcat( L". ", esc );
|
||||
free( esc );
|
||||
|
||||
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
tm = (time_t *)malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
@ -1044,7 +1044,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
{
|
||||
on_load(cmd );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Source the completion file for the specified completion
|
||||
*/
|
||||
|
@ -1054,7 +1054,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
Do nothing on failiure
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
free(src_cmd);
|
||||
reloaded = 1;
|
||||
}
|
||||
|
@ -1064,9 +1064,9 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
If we are rechecking an autoload file, and it hasn't
|
||||
changed, update the 'last check' timestamp.
|
||||
*/
|
||||
tm[1] = time(0);
|
||||
tm[1] = time(0);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1078,18 +1078,18 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
|||
*/
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
tm = (time_t *)malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
|
||||
tm[0] = 0;
|
||||
tm[1] = time(0);
|
||||
hash_put( &loaded->load_time, intern( cmd ), tm );
|
||||
}
|
||||
|
||||
return reloaded;
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments )
|
||||
|
@ -1099,7 +1099,7 @@ void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments )
|
|||
wchar_t **arg;
|
||||
string_buffer_t sb;
|
||||
sb_init( &sb );
|
||||
|
||||
|
||||
for( arg=argv; *arg; arg++ )
|
||||
{
|
||||
if( arg != argv )
|
||||
|
@ -1108,31 +1108,31 @@ void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments )
|
|||
}
|
||||
sb_append( &sb, *arg );
|
||||
}
|
||||
|
||||
|
||||
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
else
|
||||
{
|
||||
env_set( L"argv", 0, ENV_LOCAL );
|
||||
}
|
||||
}
|
||||
|
||||
if( named_arguments )
|
||||
{
|
||||
wchar_t **arg;
|
||||
int i;
|
||||
|
||||
|
||||
for( i=0, arg=argv; i < al_get_count( named_arguments ); i++ )
|
||||
{
|
||||
env_set( al_get( named_arguments, i ), *arg, ENV_LOCAL );
|
||||
env_set( (const wchar_t *)al_get( named_arguments, i ), *arg, ENV_LOCAL );
|
||||
|
||||
if( *arg )
|
||||
arg++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
|
||||
|
@ -1141,14 +1141,14 @@ wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
|
|||
wchar_t *unescaped;
|
||||
|
||||
CHECK( str, 0 );
|
||||
|
||||
|
||||
unescaped = wcsdup(str);
|
||||
|
||||
if( !unescaped )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
|
||||
for( in=out=unescaped; *in; in++ )
|
||||
{
|
||||
switch( *in )
|
||||
|
@ -1163,25 +1163,25 @@ wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
|
|||
*(out++)=*in;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'*':
|
||||
{
|
||||
*(out++)=ANY_STRING;
|
||||
*(out++)=ANY_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'?':
|
||||
{
|
||||
*(out++)=ANY_CHAR;
|
||||
*(out++)=ANY_CHAR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
*(out++)=*in;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return unescaped;
|
||||
}
|
||||
|
|
18
parse_util.h
18
parse_util.h
|
@ -11,7 +11,7 @@
|
|||
|
||||
/**
|
||||
Find the beginning and end of the first subshell in the specified string.
|
||||
|
||||
|
||||
\param in the string to search for subshells
|
||||
\param begin the starting paranthesis of the subshell
|
||||
\param end the ending paranthesis of the subshell
|
||||
|
@ -19,8 +19,8 @@
|
|||
\return -1 on syntax error, 0 if no subshells exist and 1 on sucess
|
||||
*/
|
||||
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
wchar_t **begin,
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
wchar_t **begin,
|
||||
wchar_t **end,
|
||||
int flags );
|
||||
|
||||
|
@ -38,7 +38,7 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
|||
*/
|
||||
void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b );
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
|||
*/
|
||||
void parse_util_process_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b );
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ void parse_util_process_extent( const wchar_t *buff,
|
|||
*/
|
||||
void parse_util_job_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
wchar_t **a,
|
||||
wchar_t **a,
|
||||
wchar_t **b );
|
||||
|
||||
/**
|
||||
|
@ -84,7 +84,7 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
int cursor_pos,
|
||||
wchar_t **tok_begin,
|
||||
wchar_t **tok_end,
|
||||
wchar_t **prev_begin,
|
||||
wchar_t **prev_begin,
|
||||
wchar_t **prev_end );
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ int parse_util_get_offset( wchar_t *buff, int line, int line_offset );
|
|||
not load it multiple times unless it's timestamp changes or
|
||||
parse_util_unload is called.
|
||||
|
||||
Autoloading one file may unload another.
|
||||
Autoloading one file may unload another.
|
||||
|
||||
\param cmd the filename to search for. The suffix '.fish' is always added to this name
|
||||
\param path_var_name the environment variable giving the search path
|
||||
|
@ -153,7 +153,7 @@ int parse_util_unload( const wchar_t *cmd,
|
|||
|
||||
/**
|
||||
Set the argv environment variable to the specified null-terminated
|
||||
array of strings.
|
||||
array of strings.
|
||||
*/
|
||||
void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments );
|
||||
|
||||
|
|
572
parser.cpp
572
parser.cpp
File diff suppressed because it is too large
Load diff
44
parser.h
44
parser.h
|
@ -1,5 +1,5 @@
|
|||
/** \file parser.h
|
||||
The fish parser.
|
||||
The fish parser.
|
||||
*/
|
||||
|
||||
#ifndef FISH_PARSER_H
|
||||
|
@ -24,12 +24,12 @@ typedef struct event_block
|
|||
The types of events to block. This is interpreted as a bitset
|
||||
whete the value is 1 for every bit corresponding to a blocked
|
||||
event type. For example, if EVENT_VARIABLE type events should
|
||||
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
|
||||
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
|
||||
|
||||
Note that EVENT_ANY can be used to specify any event.
|
||||
*/
|
||||
int type;
|
||||
|
||||
|
||||
/**
|
||||
The next event_block struct
|
||||
*/
|
||||
|
@ -40,7 +40,7 @@ typedef struct event_block
|
|||
|
||||
|
||||
/**
|
||||
block_t represents a block of commands.
|
||||
block_t represents a block of commands.
|
||||
*/
|
||||
typedef struct block
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ typedef struct block
|
|||
int skip; /**< Whether execution of the commands in this block should be skipped */
|
||||
int tok_pos; /**< The start index of the block */
|
||||
int had_command; /**< Set to non-zero once a command has been executed in this block */
|
||||
|
||||
|
||||
/**
|
||||
Status for the current loop block. Can be any of the values from the loop_status enum.
|
||||
*/
|
||||
|
@ -63,18 +63,18 @@ typedef struct block
|
|||
Block type-specific data
|
||||
*/
|
||||
void *data;
|
||||
|
||||
|
||||
/**
|
||||
First block type specific variable
|
||||
*/
|
||||
union
|
||||
union
|
||||
{
|
||||
int while_state; /**< True if the loop condition has not yet been evaluated*/
|
||||
wchar_t *for_variable; /**< Name of the variable to loop over */
|
||||
int if_state; /**< The state of the if block, can be one of IF_STATE_UNTESTED, IF_STATE_FALSE, IF_STATE_TRUE */
|
||||
wchar_t *switch_value; /**< The value to test in a switch block */
|
||||
const wchar_t *source_dest; /**< The name of the file to source*/
|
||||
event_t *event; /**<The event that triggered this block */
|
||||
event_t *event; /**<The event that triggered this block */
|
||||
wchar_t *function_call_name;
|
||||
} param1;
|
||||
|
||||
|
@ -83,7 +83,7 @@ typedef struct block
|
|||
*/
|
||||
union
|
||||
{
|
||||
array_list_t for_vars; /**< List of values for a for block */
|
||||
array_list_t for_vars; /**< List of values for a for block */
|
||||
int switch_taken; /**< Whether a switch match has already been found */
|
||||
process_t *function_call_process; /**< The process representing this function call */
|
||||
} param2;
|
||||
|
@ -93,24 +93,24 @@ typedef struct block
|
|||
Name of file that created this block
|
||||
*/
|
||||
const wchar_t *src_filename;
|
||||
|
||||
|
||||
/**
|
||||
Line number where this block was created
|
||||
*/
|
||||
int src_lineno;
|
||||
|
||||
|
||||
/**
|
||||
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
|
||||
*/
|
||||
event_block_t *first_event_block;
|
||||
|
||||
|
||||
/**
|
||||
Next outer block
|
||||
Next outer block
|
||||
*/
|
||||
struct block *outer;
|
||||
struct block *outer;
|
||||
} block_t;
|
||||
|
||||
/**
|
||||
/**
|
||||
Types of blocks
|
||||
*/
|
||||
enum block_type
|
||||
|
@ -135,7 +135,7 @@ enum block_type
|
|||
/**
|
||||
Possible states for a loop
|
||||
*/
|
||||
enum loop_status
|
||||
enum loop_status
|
||||
{
|
||||
LOOP_NORMAL, /**< Current loop block executed as normal */
|
||||
LOOP_BREAK, /**< Current loop block should be removed */
|
||||
|
@ -159,14 +159,14 @@ enum while_status
|
|||
/**
|
||||
Errors that can be generated by the parser
|
||||
*/
|
||||
enum parser_error
|
||||
enum parser_error
|
||||
{
|
||||
/**
|
||||
No error
|
||||
*/
|
||||
NO_ERR=0,
|
||||
/**
|
||||
An error in the syntax
|
||||
An error in the syntax
|
||||
*/
|
||||
SYNTAX_ERROR,
|
||||
/**
|
||||
|
@ -187,7 +187,7 @@ extern block_t *current_block;
|
|||
extern event_block_t *global_event_block;
|
||||
|
||||
/**
|
||||
Current block level io redirections
|
||||
Current block level io redirections
|
||||
*/
|
||||
extern io_data_t *block_io;
|
||||
|
||||
|
@ -213,7 +213,7 @@ int eval_args( const wchar_t *line,
|
|||
array_list_t *output );
|
||||
|
||||
/**
|
||||
Sets the current evaluation error. This function should only be used by libraries that are called by
|
||||
Sets the current evaluation error. This function should only be used by libraries that are called by
|
||||
|
||||
\param ec The new error code
|
||||
\param p The character offset at which the error occured
|
||||
|
@ -224,7 +224,7 @@ void error( int ec, int p, const wchar_t *str, ... );
|
|||
|
||||
/**
|
||||
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
|
||||
Example:
|
||||
Example:
|
||||
|
||||
init.fish (line 127): ls|grep pancake
|
||||
*/
|
||||
|
@ -315,7 +315,7 @@ void parser_init();
|
|||
void parser_destroy();
|
||||
|
||||
/**
|
||||
This function checks if the specified string is a help option.
|
||||
This function checks if the specified string is a help option.
|
||||
|
||||
\param s the string to test
|
||||
\param min_match is the minimum number of characters that must match in a long style option, i.e. the longest common prefix between --help and any other option. If less than 3, 3 will be assumed.
|
||||
|
|
|
@ -18,7 +18,7 @@ int parser_keywords_is_switch( const wchar_t *cmd )
|
|||
{
|
||||
if( wcscmp( cmd, L"--" ) == 0 )
|
||||
return ARG_SKIP;
|
||||
else
|
||||
else
|
||||
return cmd[0] == L'-';
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ int parser_keywords_is_subcommand( const wchar_t *cmd )
|
|||
L"and",
|
||||
L"or",
|
||||
L"not" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
int parser_keywords_is_block( const wchar_t *word)
|
||||
|
|
|
@ -9,7 +9,7 @@ Functions having to do with parser keywords, like testing if a function is a blo
|
|||
/**
|
||||
Return valuse for parser_keywords_is_switch()
|
||||
*/
|
||||
enum
|
||||
enum
|
||||
{
|
||||
ARG_NON_SWITCH,
|
||||
ARG_SWITCH,
|
||||
|
@ -27,7 +27,7 @@ int parser_keywords_is_switch( const wchar_t *cmd );
|
|||
|
||||
|
||||
/**
|
||||
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
||||
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
||||
|
||||
\param cmd The command name to test
|
||||
\return 1 of the command parameter is a command, 0 otherwise
|
||||
|
|
218
path.cpp
218
path.cpp
|
@ -25,14 +25,115 @@
|
|||
*/
|
||||
#define MISSING_COMMAND_ERR_MSG _( L"Error while searching for command '%ls'" )
|
||||
|
||||
bool path_get_path_string(const wcstring &cmd_str, wcstring &output, const env_vars &vars)
|
||||
{
|
||||
const wchar_t * const cmd = cmd_str.c_str();
|
||||
int err = ENOENT;
|
||||
debug( 3, L"path_get_path_string( '%ls' )", cmd );
|
||||
|
||||
if(wcschr( cmd, L'/' ) != 0 )
|
||||
{
|
||||
if( waccess( cmd, X_OK )==0 )
|
||||
{
|
||||
struct stat buff;
|
||||
if(wstat( cmd, &buff ))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISREG(buff.st_mode))
|
||||
{
|
||||
output = cmd_str;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EACCES;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//struct stat buff;
|
||||
//wstat( cmd, &buff );
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const wchar_t *path = vars.get(L"PATH");
|
||||
if( path == 0 )
|
||||
{
|
||||
if( contains( PREFIX L"/bin", L"/bin", L"/usr/bin" ) )
|
||||
{
|
||||
path = L"/bin" ARRAY_SEP_STR L"/usr/bin";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
|
||||
}
|
||||
}
|
||||
|
||||
wcstokenizer tokenizer(path, ARRAY_SEP_STR);
|
||||
wcstring new_cmd;
|
||||
while (tokenizer.next(new_cmd))
|
||||
{
|
||||
size_t path_len = new_cmd.size();
|
||||
if (path_len == 0) continue;
|
||||
|
||||
append_path_component(new_cmd, cmd_str);
|
||||
if( waccess( new_cmd.c_str(), X_OK )==0 )
|
||||
{
|
||||
struct stat buff;
|
||||
if( wstat( new_cmd.c_str(), &buff )==-1 )
|
||||
{
|
||||
if( errno != EACCES )
|
||||
{
|
||||
wperror( L"stat" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( S_ISREG(buff.st_mode) )
|
||||
{
|
||||
output = new_cmd;
|
||||
return true;
|
||||
}
|
||||
err = EACCES;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( errno )
|
||||
{
|
||||
case ENOENT:
|
||||
case ENAMETOOLONG:
|
||||
case EACCES:
|
||||
case ENOTDIR:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
debug( 1,
|
||||
MISSING_COMMAND_ERR_MSG,
|
||||
new_cmd.c_str() );
|
||||
wperror( L"access" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errno = err;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
||||
{
|
||||
wchar_t *path;
|
||||
|
||||
int err = ENOENT;
|
||||
|
||||
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
debug( 3, L"path_get_path( '%ls' )", cmd );
|
||||
|
@ -46,7 +147,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( S_ISREG(buff.st_mode) )
|
||||
return halloc_wcsdup( context, cmd );
|
||||
else
|
||||
|
@ -61,7 +162,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
wstat( cmd, &buff );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -77,12 +178,12 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Allocate string long enough to hold the whole command
|
||||
*/
|
||||
wchar_t *new_cmd = halloc( context, sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
|
||||
|
||||
wchar_t *new_cmd = (wchar_t *)halloc( context, sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
|
||||
|
||||
/*
|
||||
We tokenize a copy of the path, since strtok modifies
|
||||
its arguments
|
||||
|
@ -90,7 +191,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
wchar_t *path_cpy = wcsdup( path );
|
||||
wchar_t *nxt_path = path;
|
||||
wchar_t *state;
|
||||
|
||||
|
||||
if( (new_cmd==0) || (path_cpy==0) )
|
||||
{
|
||||
DIE_MEM();
|
||||
|
@ -124,7 +225,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
return new_cmd;
|
||||
}
|
||||
err = EACCES;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -154,7 +255,82 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
|
|||
}
|
||||
|
||||
|
||||
wchar_t *path_get_cdpath( void *context, wchar_t *dir )
|
||||
bool path_get_cdpath_string(const wcstring &dir_str, wcstring &result, const env_vars &vars)
|
||||
{
|
||||
wchar_t *res = 0;
|
||||
int err = ENOENT;
|
||||
bool success = false;
|
||||
|
||||
const wchar_t *const dir = dir_str.c_str();
|
||||
if( dir[0] == L'/'|| (wcsncmp( dir, L"./", 2 )==0) )
|
||||
{
|
||||
struct stat buf;
|
||||
if( wstat( dir, &buf ) == 0 )
|
||||
{
|
||||
if( S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
result = dir_str;
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ENOTDIR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const wchar_t *path = vars.get(L"CDPATH");
|
||||
if( !path || !wcslen(path) )
|
||||
{
|
||||
path = L".";
|
||||
}
|
||||
|
||||
wcstokenizer tokenizer(path, ARRAY_SEP_STR);
|
||||
wcstring next_path;
|
||||
while (tokenizer.next(next_path))
|
||||
{
|
||||
expand_tilde(next_path);
|
||||
if (next_path.size() == 0) continue;
|
||||
|
||||
wcstring whole_path = next_path;
|
||||
append_path_component(whole_path, dir);
|
||||
|
||||
struct stat buf;
|
||||
if( wstat( whole_path.c_str(), &buf ) == 0 )
|
||||
{
|
||||
if( S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
result = whole_path;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ENOTDIR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( lwstat( whole_path.c_str(), &buf ) == 0 )
|
||||
{
|
||||
err = EROTTEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !success )
|
||||
{
|
||||
errno = err;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wchar_t *path_get_cdpath( void *context, const wchar_t *dir )
|
||||
{
|
||||
wchar_t *res = 0;
|
||||
int err = ENOENT;
|
||||
|
@ -205,7 +381,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
|
|||
nxt_path != 0;
|
||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||
{
|
||||
wchar_t *expanded_path = expand_tilde( wcsdup(nxt_path) );
|
||||
wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) );
|
||||
|
||||
// debug( 2, L"woot %ls\n", expanded_path );
|
||||
|
||||
|
@ -229,7 +405,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
|
|||
if( S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
res = whole_path;
|
||||
halloc_register( context, whole_path );
|
||||
halloc_register( context, whole_path );
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -244,7 +420,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
|
|||
err = EROTTEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( whole_path );
|
||||
}
|
||||
free( path_cpy );
|
||||
|
@ -264,7 +440,7 @@ wchar_t *path_get_config( void *context)
|
|||
wchar_t *xdg_dir, *home;
|
||||
int done = 0;
|
||||
wchar_t *res = 0;
|
||||
|
||||
|
||||
xdg_dir = env_get( L"XDG_CONFIG_HOME" );
|
||||
if( xdg_dir )
|
||||
{
|
||||
|
@ -277,10 +453,10 @@ wchar_t *path_get_config( void *context)
|
|||
{
|
||||
free( res );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
home = env_get( L"HOME" );
|
||||
if( home )
|
||||
{
|
||||
|
@ -295,7 +471,7 @@ wchar_t *path_get_config( void *context)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( done )
|
||||
{
|
||||
halloc_register_function( context, &free, res );
|
||||
|
@ -306,16 +482,16 @@ wchar_t *path_get_config( void *context)
|
|||
debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
wchar_t *path_make_canonical( void *context, const wchar_t *path )
|
||||
{
|
||||
wchar_t *res = halloc_wcsdup( context, path );
|
||||
wchar_t *in, *out;
|
||||
|
||||
|
||||
in = out = res;
|
||||
|
||||
|
||||
while( *in )
|
||||
{
|
||||
if( *in == L'/' )
|
||||
|
@ -326,7 +502,7 @@ wchar_t *path_make_canonical( void *context, const wchar_t *path )
|
|||
}
|
||||
}
|
||||
*out = *in;
|
||||
|
||||
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
|
@ -340,7 +516,7 @@ wchar_t *path_make_canonical( void *context, const wchar_t *path )
|
|||
out--;
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
14
path.h
14
path.h
|
@ -25,36 +25,40 @@ wchar_t *path_get_config( void *context);
|
|||
|
||||
/**
|
||||
Finds the full path of an executable in a newly allocated string.
|
||||
|
||||
|
||||
\param cmd The name of the executable.
|
||||
\param context the halloc context to use for memory allocations
|
||||
\return 0 if the command can not be found, the path of the command otherwise.
|
||||
*/
|
||||
wchar_t *path_get_path( void *context, const wchar_t *cmd );
|
||||
|
||||
class env_vars;
|
||||
bool path_get_path_string(const wcstring &cmd, wcstring &output, const env_vars &vars);
|
||||
|
||||
/**
|
||||
Returns the full path of the specified directory, using the CDPATH
|
||||
variable as a list of base directories for relative paths. The
|
||||
returned string is allocated using halloc and the specified
|
||||
context.
|
||||
|
||||
|
||||
If no valid path is found, null is returned and errno is set to
|
||||
ENOTDIR if at least one such path was found, but it did not point
|
||||
to a directory, EROTTEN if a arotten symbolic link was found, or
|
||||
ENOENT if no file of the specified name was found. If both a rotten
|
||||
symlink and a file are found, it is undefined which error status
|
||||
will be returned.
|
||||
|
||||
|
||||
\param in The name of the directory.
|
||||
\param context the halloc context to use for memory allocations
|
||||
\return 0 if the command can not be found, the path of the command otherwise.
|
||||
*/
|
||||
wchar_t *path_get_cdpath( void *context, wchar_t *in );
|
||||
wchar_t *path_get_cdpath( void *context, const wchar_t *in );
|
||||
bool path_get_cdpath_string(const wcstring &in, wcstring &out, const env_vars &vars);
|
||||
|
||||
/**
|
||||
Remove doulbe slashes and trailing slashes from a path,
|
||||
e.g. transform foo//bar/ into foo/bar.
|
||||
|
||||
|
||||
The returned string is allocated using the specified halloc
|
||||
context.
|
||||
*/
|
||||
|
|
|
@ -21,14 +21,14 @@ void print_help( char *c, int fd )
|
|||
{
|
||||
char cmd[ CMD_LEN];
|
||||
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
|
||||
|
||||
|
||||
if( printed < CMD_LEN )
|
||||
{
|
||||
if( (system( cmd ) == -1) )
|
||||
{
|
||||
write_loop(2, HELP_ERR, strlen(HELP_ERR));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef FISH_PRINT_HELP_H
|
||||
#define FISH_PRINT_HELP_H
|
||||
|
||||
/**
|
||||
/**
|
||||
Print help message for the specified command
|
||||
*/
|
||||
|
||||
|
|
412
proc.cpp
412
proc.cpp
|
@ -7,7 +7,7 @@ will call proc to create representations of the running jobs as
|
|||
needed.
|
||||
|
||||
Some of the code in this file is based on code from the Glibc manual.
|
||||
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -76,7 +76,7 @@ Some of the code in this file is based on code from the Glibc manual.
|
|||
#include "output.h"
|
||||
|
||||
/**
|
||||
Size of message buffer
|
||||
Size of message buffer
|
||||
*/
|
||||
#define MESS_SIZE 256
|
||||
|
||||
|
@ -85,13 +85,13 @@ Some of the code in this file is based on code from the Glibc manual.
|
|||
*/
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
/**
|
||||
Status of last process to exit
|
||||
/**
|
||||
Status of last process to exit
|
||||
*/
|
||||
static int last_status=0;
|
||||
|
||||
/**
|
||||
Signal flag
|
||||
Signal flag
|
||||
*/
|
||||
static sig_atomic_t got_signal=0;
|
||||
|
||||
|
@ -139,7 +139,7 @@ void proc_init()
|
|||
|
||||
|
||||
/**
|
||||
Remove job from list of jobs
|
||||
Remove job from list of jobs
|
||||
*/
|
||||
static int job_remove( job_t *j )
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ static int job_remove( job_t *j )
|
|||
sanity_lose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( prev == 0 )
|
||||
first_job = j->next;
|
||||
else
|
||||
|
@ -184,7 +184,7 @@ void proc_destroy()
|
|||
{
|
||||
debug( 2, L"freeing leaked job %ls", first_job->command );
|
||||
job_free( first_job );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void proc_set_last_status( int s )
|
||||
|
@ -201,25 +201,25 @@ job_t *job_create()
|
|||
{
|
||||
int free_id=1;
|
||||
job_t *res;
|
||||
|
||||
|
||||
while( job_get( free_id ) != 0 )
|
||||
free_id++;
|
||||
res = halloc( 0, sizeof(job_t) );
|
||||
res = (job_t *)halloc( 0, sizeof(job_t) );
|
||||
res->next = first_job;
|
||||
res->job_id = free_id;
|
||||
first_job = res;
|
||||
|
||||
job_set_flag( res,
|
||||
JOB_CONTROL,
|
||||
(job_control_mode==JOB_CONTROL_ALL) ||
|
||||
job_set_flag( res,
|
||||
JOB_CONTROL,
|
||||
(job_control_mode==JOB_CONTROL_ALL) ||
|
||||
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive)) );
|
||||
|
||||
// if( res->job_id > 2 )
|
||||
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
||||
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
job_t *job_get( int id )
|
||||
{
|
||||
job_t *res = first_job;
|
||||
|
@ -227,7 +227,7 @@ job_t *job_get( int id )
|
|||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
while( res != 0 )
|
||||
{
|
||||
if( res->job_id == id )
|
||||
|
@ -240,7 +240,7 @@ job_t *job_get( int id )
|
|||
job_t *job_get_from_pid( int pid )
|
||||
{
|
||||
job_t *res = first_job;
|
||||
|
||||
|
||||
while( res != 0 )
|
||||
{
|
||||
if( res->pgid == pid )
|
||||
|
@ -251,8 +251,8 @@ job_t *job_get_from_pid( int pid )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Return true if all processes in the job have stopped or completed.
|
||||
/*
|
||||
Return true if all processes in the job have stopped or completed.
|
||||
|
||||
\param j the job to test
|
||||
*/
|
||||
|
@ -271,20 +271,20 @@ int job_is_stopped( const job_t *j )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Return true if the last processes in the job has completed.
|
||||
/*
|
||||
Return true if the last processes in the job has completed.
|
||||
|
||||
\param j the job to test
|
||||
*/
|
||||
int job_is_completed( const job_t *j )
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
|
||||
for (p = j->first_process; p->next; p = p->next)
|
||||
;
|
||||
|
||||
|
||||
return p->completed;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void job_set_flag( job_t *j, int flag, int set )
|
||||
|
@ -301,10 +301,10 @@ int job_get_flag( job_t *j, int flag )
|
|||
}
|
||||
|
||||
int job_signal( job_t *j, int signal )
|
||||
{
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
int res = 0;
|
||||
|
||||
|
||||
if( j->pgid != my_pid )
|
||||
{
|
||||
res = killpg( j->pgid, SIGHUP );
|
||||
|
@ -337,7 +337,7 @@ int job_signal( job_t *j, int signal )
|
|||
|
||||
/**
|
||||
Store the status of the process pid that was returned by waitpid.
|
||||
Return 0 if all went well, nonzero otherwise.
|
||||
Return 0 if all went well, nonzero otherwise.
|
||||
*/
|
||||
static void mark_process_status( job_t *j,
|
||||
process_t *p,
|
||||
|
@ -345,19 +345,19 @@ static void mark_process_status( job_t *j,
|
|||
{
|
||||
// debug( 0, L"Process %ls %ls", p->argv[0], WIFSTOPPED (status)?L"stopped":(WIFEXITED( status )?L"exited":(WIFSIGNALED( status )?L"signaled to exit":L"BLARGH")) );
|
||||
p->status = status;
|
||||
|
||||
|
||||
if (WIFSTOPPED (status))
|
||||
{
|
||||
p->stopped = 1;
|
||||
}
|
||||
else if (WIFSIGNALED(status) || WIFEXITED(status))
|
||||
else if (WIFSIGNALED(status) || WIFEXITED(status))
|
||||
{
|
||||
p->completed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssize_t ignore;
|
||||
|
||||
|
||||
/* This should never be reached */
|
||||
p->completed = 1;
|
||||
|
||||
|
@ -388,10 +388,10 @@ static void handle_child_status( pid_t pid, int status )
|
|||
int found_proc = 0;
|
||||
job_t *j=0;
|
||||
process_t *p=0;
|
||||
// char mess[MESS_SIZE];
|
||||
found_proc = 0;
|
||||
// char mess[MESS_SIZE];
|
||||
found_proc = 0;
|
||||
/*
|
||||
snprintf( mess,
|
||||
snprintf( mess,
|
||||
MESS_SIZE,
|
||||
"Process %d\n",
|
||||
(int) pid );
|
||||
|
@ -410,8 +410,8 @@ static void handle_child_status( pid_t pid, int status )
|
|||
"Process %d is %ls from job %ls\n",
|
||||
(int) pid, p->actual_cmd, j->command );
|
||||
write( 2, mess, strlen(mess ));
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
mark_process_status ( j, p, status);
|
||||
if( p->completed && prev != 0 )
|
||||
{
|
||||
|
@ -420,7 +420,7 @@ static void handle_child_status( pid_t pid, int status )
|
|||
/* snprintf( mess,
|
||||
MESS_SIZE,
|
||||
"Kill previously uncompleted process %ls (%d)\n",
|
||||
prev->actual_cmd,
|
||||
prev->actual_cmd,
|
||||
prev->pid );
|
||||
write( 2, mess, strlen(mess ));
|
||||
*/
|
||||
|
@ -435,15 +435,15 @@ static void handle_child_status( pid_t pid, int status )
|
|||
}
|
||||
|
||||
|
||||
if( WIFSIGNALED( status ) &&
|
||||
( WTERMSIG(status)==SIGINT ||
|
||||
if( WIFSIGNALED( status ) &&
|
||||
( WTERMSIG(status)==SIGINT ||
|
||||
WTERMSIG(status)==SIGQUIT ) )
|
||||
{
|
||||
if( !is_interactive_session )
|
||||
{
|
||||
{
|
||||
struct sigaction act;
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=0;
|
||||
act.sa_flags=0;
|
||||
act.sa_handler=SIG_DFL;
|
||||
sigaction( SIGINT, &act, 0 );
|
||||
sigaction( SIGQUIT, &act, 0 );
|
||||
|
@ -458,34 +458,34 @@ static void handle_child_status( pid_t pid, int status )
|
|||
{
|
||||
c->skip=1;
|
||||
c=c->outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !found_proc )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
A child we lost track of?
|
||||
|
||||
|
||||
There have been bugs in both subshell handling and in
|
||||
builtin handling that have caused this previously...
|
||||
*/
|
||||
/* snprintf( mess,
|
||||
/* snprintf( mess,
|
||||
MESS_SIZE,
|
||||
"Process %d not found by %d\n",
|
||||
(int) pid, (int)getpid() );
|
||||
|
||||
write( 2, mess, strlen(mess ));
|
||||
*/
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void job_handle_signal ( int signal, siginfo_t *info, void *con )
|
||||
{
|
||||
|
||||
|
||||
int status;
|
||||
pid_t pid;
|
||||
int errno_old = errno;
|
||||
|
@ -503,19 +503,19 @@ void job_handle_signal ( int signal, siginfo_t *info, void *con )
|
|||
{
|
||||
errno=errno_old;
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
||||
handle_child_status( pid, status );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kill( 0, SIGIO );
|
||||
errno=errno_old;
|
||||
}
|
||||
|
||||
/**
|
||||
Format information about job status for the user to look at.
|
||||
/**
|
||||
Format information about job status for the user to look at.
|
||||
|
||||
\param j the job to test
|
||||
\param status a string description of the job exit type
|
||||
|
@ -531,46 +531,46 @@ static void format_job_info( const job_t *j, const wchar_t *status )
|
|||
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||
{
|
||||
|
||||
|
||||
event.type=type;
|
||||
event.param1.pid = pid;
|
||||
|
||||
al_push( &event.arguments, msg );
|
||||
|
||||
al_push( &event.arguments, msg );
|
||||
|
||||
sb_printf( &event_pid, L"%d", pid );
|
||||
al_push( &event.arguments, event_pid.buff );
|
||||
|
||||
sb_printf( &event_status, L"%d", status );
|
||||
|
||||
sb_printf( &event_status, L"%d", status );
|
||||
al_push( &event.arguments, event_status.buff );
|
||||
|
||||
event_fire( &event );
|
||||
|
||||
al_truncate( &event.arguments, 0 );
|
||||
sb_clear( &event_pid );
|
||||
sb_clear( &event_status );
|
||||
}
|
||||
sb_clear( &event_pid );
|
||||
sb_clear( &event_status );
|
||||
}
|
||||
|
||||
int job_reap( int interactive )
|
||||
{
|
||||
job_t *j, *jnext;
|
||||
job_t *j, *jnext;
|
||||
int found=0;
|
||||
|
||||
|
||||
static int locked = 0;
|
||||
|
||||
locked++;
|
||||
|
||||
|
||||
locked++;
|
||||
|
||||
/*
|
||||
job_read may fire an event handler, we do not want to call
|
||||
ourselves recursively (to avoid infinite recursion).
|
||||
*/
|
||||
if( locked>1 )
|
||||
return 0;
|
||||
|
||||
|
||||
for( j=first_job; j; j=jnext)
|
||||
{
|
||||
{
|
||||
process_t *p;
|
||||
jnext = j->next;
|
||||
|
||||
|
||||
/*
|
||||
If we are reaping only jobs who do not need status messages
|
||||
sent to the console, do not consider reaping jobs that need
|
||||
|
@ -580,28 +580,28 @@ int job_reap( int interactive )
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
int s;
|
||||
if( !p->completed )
|
||||
continue;
|
||||
|
||||
|
||||
if( !p->pid )
|
||||
continue;
|
||||
|
||||
continue;
|
||||
|
||||
s = p->status;
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
|
||||
if( WIFSIGNALED(s) )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
Ignore signal SIGPIPE.We issue it ourselves to the pipe
|
||||
writer when the pipe reader dies.
|
||||
*/
|
||||
if( WTERMSIG(s) != SIGPIPE )
|
||||
{
|
||||
{
|
||||
int proc_is_job = ((p==j->first_process) && (p->next == 0));
|
||||
if( proc_is_job )
|
||||
job_set_flag( j, JOB_NOTIFIED, 1 );
|
||||
|
@ -611,7 +611,7 @@ int job_reap( int interactive )
|
|||
fwprintf( stdout,
|
||||
_( L"%ls: Job %d, \'%ls\' terminated by signal %ls (%ls)" ),
|
||||
program_name,
|
||||
j->job_id,
|
||||
j->job_id,
|
||||
j->command,
|
||||
sig2wcs(WTERMSIG(p->status)),
|
||||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
|
@ -627,43 +627,43 @@ int job_reap( int interactive )
|
|||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
tputs(clr_eol,1,&writeb);
|
||||
fwprintf (stdout, L"\n" );
|
||||
found=1;
|
||||
found=1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Clear status so it is not reported more than once
|
||||
*/
|
||||
p->status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
If all processes have completed, tell the user the job has
|
||||
completed and delete it from the active job list.
|
||||
completed and delete it from the active job list.
|
||||
*/
|
||||
if( job_is_completed( j ) )
|
||||
if( job_is_completed( j ) )
|
||||
{
|
||||
if( !job_get_flag( j, JOB_FOREGROUND) && !job_get_flag( j, JOB_NOTIFIED ) && !job_get_flag( j, JOB_SKIP_NOTIFICATION ) )
|
||||
{
|
||||
format_job_info( j, _( L"ended" ) );
|
||||
found=1;
|
||||
}
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||
|
||||
job_free(j);
|
||||
}
|
||||
else if( job_is_stopped( j ) && !job_get_flag( j, JOB_NOTIFIED ) )
|
||||
}
|
||||
else if( job_is_stopped( j ) && !job_get_flag( j, JOB_NOTIFIED ) )
|
||||
{
|
||||
/*
|
||||
Notify the user about newly stopped jobs.
|
||||
/*
|
||||
Notify the user about newly stopped jobs.
|
||||
*/
|
||||
if( !job_get_flag( j, JOB_SKIP_NOTIFICATION ) )
|
||||
{
|
||||
format_job_info( j, _( L"stopped" ) );
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
job_set_flag( j, JOB_NOTIFIED, 1 );
|
||||
}
|
||||
}
|
||||
|
@ -672,8 +672,8 @@ int job_reap( int interactive )
|
|||
fflush( stdout );
|
||||
|
||||
locked = 0;
|
||||
|
||||
return found;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
@ -692,36 +692,36 @@ unsigned long proc_get_jiffies( process_t *p )
|
|||
wchar_t fn[FN_SIZE];
|
||||
|
||||
char state;
|
||||
int pid, ppid, pgrp,
|
||||
int pid, ppid, pgrp,
|
||||
session, tty_nr, tpgid,
|
||||
exit_signal, processor;
|
||||
|
||||
long int cutime, cstime, priority,
|
||||
nice, placeholder, itrealvalue,
|
||||
exit_signal, processor;
|
||||
|
||||
long int cutime, cstime, priority,
|
||||
nice, placeholder, itrealvalue,
|
||||
rss;
|
||||
unsigned long int flags, minflt, cminflt,
|
||||
majflt, cmajflt, utime,
|
||||
stime, starttime, vsize,
|
||||
unsigned long int flags, minflt, cminflt,
|
||||
majflt, cmajflt, utime,
|
||||
stime, starttime, vsize,
|
||||
rlim, startcode, endcode,
|
||||
startstack, kstkesp, kstkeip,
|
||||
signal, blocked, sigignore,
|
||||
sigcatch, wchan, nswap, cnswap;
|
||||
char comm[1024];
|
||||
|
||||
|
||||
if( p->pid <= 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
swprintf( fn, FN_SIZE, L"/proc/%d/stat", p->pid );
|
||||
|
||||
|
||||
FILE *f = wfopen( fn, "r" );
|
||||
if( !f )
|
||||
return 0;
|
||||
|
||||
int count = fscanf( f,
|
||||
"%d %s %c "
|
||||
|
||||
int count = fscanf( f,
|
||||
"%d %s %c "
|
||||
"%d %d %d "
|
||||
"%d %d %lu "
|
||||
|
||||
|
||||
"%lu %lu %lu "
|
||||
"%lu %lu %lu "
|
||||
"%ld %ld %ld "
|
||||
|
@ -735,15 +735,15 @@ unsigned long proc_get_jiffies( process_t *p )
|
|||
"%lu %lu %lu "
|
||||
|
||||
"%lu %d %d ",
|
||||
|
||||
&pid, comm, &state,
|
||||
&ppid, &pgrp, &session,
|
||||
|
||||
&pid, comm, &state,
|
||||
&ppid, &pgrp, &session,
|
||||
&tty_nr, &tpgid, &flags,
|
||||
|
||||
&minflt, &cminflt, &majflt,
|
||||
&cmajflt, &utime, &stime,
|
||||
&cutime, &cstime, &priority,
|
||||
|
||||
|
||||
&nice, &placeholder, &itrealvalue,
|
||||
&starttime, &vsize, &rss,
|
||||
&rlim, &startcode, &endcode,
|
||||
|
@ -765,7 +765,7 @@ unsigned long proc_get_jiffies( process_t *p )
|
|||
*/
|
||||
fclose( f );
|
||||
return utime+stime+cutime+cstime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -775,14 +775,14 @@ void proc_update_jiffies()
|
|||
{
|
||||
job_t *j;
|
||||
process_t *p;
|
||||
|
||||
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
gettimeofday( &p->last_time, 0 );
|
||||
p->last_jiffies = proc_get_jiffies( p );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,8 +791,8 @@ void proc_update_jiffies()
|
|||
|
||||
/**
|
||||
Check if there are buffers associated with the job, and select on
|
||||
them for a while if available.
|
||||
|
||||
them for a while if available.
|
||||
|
||||
\param j the job to test
|
||||
|
||||
\return 1 if buffers were avaialble, zero otherwise
|
||||
|
@ -804,7 +804,7 @@ static int select_try( job_t *j )
|
|||
io_data_t *d;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
|
||||
|
||||
for( d = j->io; d; d=d->next )
|
||||
{
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
|
@ -816,15 +816,15 @@ static int select_try( job_t *j )
|
|||
debug( 3, L"select_try on %d\n", fd );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( maxfd >= 0 )
|
||||
{
|
||||
int retval;
|
||||
struct timeval tv;
|
||||
|
||||
|
||||
tv.tv_sec=0;
|
||||
tv.tv_usec=10000;
|
||||
|
||||
|
||||
retval =select( maxfd+1, &fds, 0, 0, &tv );
|
||||
return retval > 0;
|
||||
}
|
||||
|
@ -833,7 +833,7 @@ static int select_try( job_t *j )
|
|||
}
|
||||
|
||||
/**
|
||||
Read from descriptors until they are empty.
|
||||
Read from descriptors until they are empty.
|
||||
|
||||
\param j the job to test
|
||||
*/
|
||||
|
@ -846,13 +846,13 @@ static void read_try( job_t *j )
|
|||
*/
|
||||
for( d = j->io; d; d=d->next )
|
||||
{
|
||||
|
||||
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
{
|
||||
buff=d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( buff )
|
||||
{
|
||||
debug( 3, L"proc::read_try('%ls')\n", j->command );
|
||||
|
@ -860,7 +860,7 @@ static void read_try( job_t *j )
|
|||
{
|
||||
char b[BUFFER_SIZE];
|
||||
int l;
|
||||
|
||||
|
||||
l=read_blocked( buff->param1.pipe_fd[0],
|
||||
b, BUFFER_SIZE );
|
||||
if( l==0 )
|
||||
|
@ -871,23 +871,23 @@ static void read_try( job_t *j )
|
|||
{
|
||||
if( errno != EAGAIN )
|
||||
{
|
||||
debug( 1,
|
||||
debug( 1,
|
||||
_( L"An error occured while reading output from code block" ) );
|
||||
wperror( L"read_try" );
|
||||
}
|
||||
wperror( L"read_try" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_append( buff->param2.out_buffer, b, l );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Give ownership of the terminal to the specified job.
|
||||
Give ownership of the terminal to the specified job.
|
||||
|
||||
\param j The job to give the terminal to.
|
||||
|
||||
|
@ -897,19 +897,19 @@ static void read_try( job_t *j )
|
|||
*/
|
||||
static int terminal_give_to_job( job_t *j, int cont )
|
||||
{
|
||||
|
||||
|
||||
if( tcsetpgrp (0, j->pgid) )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( cont )
|
||||
{
|
||||
{
|
||||
if( tcsetattr (0, TCSADRAIN, &j->tmodes))
|
||||
{
|
||||
debug( 1,
|
||||
|
@ -926,20 +926,20 @@ static int terminal_give_to_job( job_t *j, int cont )
|
|||
/**
|
||||
Returns contol of the terminal to the shell, and saves the terminal
|
||||
attribute state to the job, so that we can restore the terminal
|
||||
ownership to the job at a later time .
|
||||
ownership to the job at a later time .
|
||||
*/
|
||||
static int terminal_return_from_job( job_t *j)
|
||||
{
|
||||
|
||||
|
||||
if( tcsetpgrp (0, getpgrp()) )
|
||||
{
|
||||
debug( 1, _( L"Could not return shell to foreground" ) );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Save jobs terminal modes.
|
||||
|
||||
/*
|
||||
Save jobs terminal modes.
|
||||
*/
|
||||
if( tcgetattr (0, &j->tmodes) )
|
||||
{
|
||||
|
@ -947,9 +947,9 @@ static int terminal_return_from_job( job_t *j)
|
|||
wperror( L"tcgetattr" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Restore the shell's terminal modes.
|
||||
|
||||
/*
|
||||
Restore the shell's terminal modes.
|
||||
*/
|
||||
if( tcsetattr (0, TCSADRAIN, &shell_modes))
|
||||
{
|
||||
|
@ -972,35 +972,35 @@ void job_continue (job_t *j, int cont)
|
|||
job_set_flag( j, JOB_NOTIFIED, 0 );
|
||||
|
||||
CHECK_BLOCK();
|
||||
|
||||
|
||||
debug( 4,
|
||||
L"Continue job %d, gid %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->job_id,
|
||||
j->pgid,
|
||||
j->command,
|
||||
job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED",
|
||||
j->command,
|
||||
job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED",
|
||||
is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE" );
|
||||
|
||||
|
||||
if( !job_is_completed( j ) )
|
||||
{
|
||||
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
|
||||
{
|
||||
{
|
||||
/* Put the job into the foreground. */
|
||||
int ok;
|
||||
|
||||
|
||||
signal_block();
|
||||
|
||||
|
||||
ok = terminal_give_to_job( j, cont );
|
||||
|
||||
signal_unblock();
|
||||
|
||||
signal_unblock();
|
||||
|
||||
if( !ok )
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Send the job a continue signal, if necessary.
|
||||
|
||||
/*
|
||||
Send the job a continue signal, if necessary.
|
||||
*/
|
||||
if( cont )
|
||||
{
|
||||
|
@ -1025,16 +1025,16 @@ void job_continue (job_t *j, int cont)
|
|||
{
|
||||
wperror (L"kill (SIGCONT)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( job_get_flag( j, JOB_FOREGROUND ) )
|
||||
{
|
||||
int quit = 0;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Wait for job to report. Looks a bit ugly because it has to
|
||||
handle the possibility that a signal is dispatched while
|
||||
running job_is_stopped().
|
||||
|
@ -1052,16 +1052,16 @@ void job_continue (job_t *j, int cont)
|
|||
|
||||
if( !quit )
|
||||
{
|
||||
|
||||
// debug( 1, L"select_try()" );
|
||||
|
||||
// debug( 1, L"select_try()" );
|
||||
switch( select_try(j) )
|
||||
{
|
||||
case 1:
|
||||
case 1:
|
||||
{
|
||||
read_try( j );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case -1:
|
||||
{
|
||||
/*
|
||||
|
@ -1072,7 +1072,7 @@ void job_continue (job_t *j, int cont)
|
|||
improvement on my 300 MHz machine) on
|
||||
short-lived jobs.
|
||||
*/
|
||||
int status;
|
||||
int status;
|
||||
pid_t pid = waitpid(-1, &status, WUNTRACED );
|
||||
if( pid > 0 )
|
||||
{
|
||||
|
@ -1091,20 +1091,20 @@ void job_continue (job_t *j, int cont)
|
|||
{
|
||||
quit = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( job_get_flag( j, JOB_FOREGROUND ) )
|
||||
{
|
||||
|
||||
|
||||
if( job_is_completed( j ))
|
||||
{
|
||||
process_t *p = j->first_process;
|
||||
|
@ -1113,51 +1113,51 @@ void job_continue (job_t *j, int cont)
|
|||
|
||||
if( WIFEXITED( p->status ) || WIFSIGNALED(p->status))
|
||||
{
|
||||
/*
|
||||
/*
|
||||
Mark process status only if we are in the foreground
|
||||
and the last process in a pipe, and it is not a short circuted builtin
|
||||
*/
|
||||
if( p->pid )
|
||||
{
|
||||
int status = proc_format_status(p->status);
|
||||
|
||||
|
||||
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?!status:status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Put the shell back in the foreground.
|
||||
/*
|
||||
Put the shell back in the foreground.
|
||||
*/
|
||||
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
|
||||
{
|
||||
int ok;
|
||||
|
||||
|
||||
signal_block();
|
||||
|
||||
ok = terminal_return_from_job( j );
|
||||
|
||||
|
||||
signal_unblock();
|
||||
|
||||
|
||||
if( !ok )
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int proc_format_status(int status)
|
||||
int proc_format_status(int status)
|
||||
{
|
||||
if( WIFSIGNALED( status ) )
|
||||
if( WIFSIGNALED( status ) )
|
||||
{
|
||||
return 128+WTERMSIG(status);
|
||||
}
|
||||
else if( WIFEXITED( status ) )
|
||||
}
|
||||
else if( WIFEXITED( status ) )
|
||||
{
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
return status;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1165,22 +1165,22 @@ void proc_sanity_check()
|
|||
{
|
||||
job_t *j;
|
||||
job_t *fg_job=0;
|
||||
|
||||
|
||||
for( j = first_job; j ; j=j->next )
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
if( !job_get_flag( j, JOB_CONSTRUCTED ) )
|
||||
continue;
|
||||
|
||||
|
||||
validate_pointer( j->command,
|
||||
_( L"Job command" ),
|
||||
|
||||
|
||||
validate_pointer( j->command,
|
||||
_( L"Job command" ),
|
||||
0 );
|
||||
validate_pointer( j->first_process,
|
||||
_( L"Process list pointer" ),
|
||||
0 );
|
||||
validate_pointer( j->next,
|
||||
validate_pointer( j->next,
|
||||
_( L"Job list pointer" ),
|
||||
1 );
|
||||
|
||||
|
@ -1191,7 +1191,7 @@ void proc_sanity_check()
|
|||
{
|
||||
if( fg_job != 0 )
|
||||
{
|
||||
debug( 0,
|
||||
debug( 0,
|
||||
_( L"More than one job in foreground: job 1: '%ls' job 2: '%ls'"),
|
||||
fg_job->command,
|
||||
j->command );
|
||||
|
@ -1199,39 +1199,39 @@ void proc_sanity_check()
|
|||
}
|
||||
fg_job = j;
|
||||
}
|
||||
|
||||
|
||||
p = j->first_process;
|
||||
while( p )
|
||||
{
|
||||
{
|
||||
validate_pointer( p->argv, _( L"Process argument list" ), 0 );
|
||||
validate_pointer( p->argv[0], _( L"Process name" ), 0 );
|
||||
validate_pointer( p->next, _( L"Process list pointer" ), 1 );
|
||||
validate_pointer( p->actual_cmd, _( L"Process command" ), 1 );
|
||||
|
||||
|
||||
if ( (p->stopped & (~0x00000001)) != 0 )
|
||||
{
|
||||
debug( 0,
|
||||
_( L"Job '%ls', process '%ls' has inconsistent state \'stopped\'=%d" ),
|
||||
j->command,
|
||||
j->command,
|
||||
p->argv[0],
|
||||
p->stopped );
|
||||
sanity_lose();
|
||||
}
|
||||
|
||||
|
||||
if ( (p->completed & (~0x00000001)) != 0 )
|
||||
{
|
||||
debug( 0,
|
||||
_( L"Job '%ls', process '%ls' has inconsistent state \'completed\'=%d" ),
|
||||
j->command,
|
||||
j->command,
|
||||
p->argv[0],
|
||||
p->completed );
|
||||
sanity_lose();
|
||||
}
|
||||
|
||||
|
||||
p=p->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void proc_push_interactive( int value )
|
||||
|
|
118
proc.h
118
proc.h
|
@ -1,11 +1,11 @@
|
|||
/** \file proc.h
|
||||
/** \file proc.h
|
||||
|
||||
Prototypes for utilities for keeping track of jobs, processes and subshells, as
|
||||
well as signal handling functions for tracking children. These
|
||||
functions do not themselves launch new processes, the exec library
|
||||
will call proc to create representations of the running jobs as
|
||||
needed.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FISH_PROC_H
|
||||
|
@ -78,19 +78,19 @@ enum
|
|||
A buffer
|
||||
*/
|
||||
INTERNAL_BUFFER,
|
||||
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
enum
|
||||
{
|
||||
JOB_CONTROL_ALL,
|
||||
JOB_CONTROL_ALL,
|
||||
JOB_CONTROL_INTERACTIVE,
|
||||
JOB_CONTROL_NONE,
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
/**
|
||||
A structure representing a single fish process. Contains variables
|
||||
for tracking process state and the process argument
|
||||
list. Actually, a fish process can be either a regular externa
|
||||
|
@ -125,7 +125,7 @@ enum
|
|||
*/
|
||||
typedef struct process
|
||||
{
|
||||
/**
|
||||
/**
|
||||
Type of process. Can be one of \c EXTERNAL, \c
|
||||
INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK,
|
||||
INTERNAL_EXEC, or INTERNAL_BUFFER
|
||||
|
@ -136,7 +136,7 @@ typedef struct process
|
|||
wchar_t **argv;
|
||||
|
||||
/** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC */
|
||||
wchar_t *actual_cmd;
|
||||
wchar_t *actual_cmd;
|
||||
|
||||
/** process ID */
|
||||
pid_t pid;
|
||||
|
@ -160,29 +160,29 @@ typedef struct process
|
|||
int count_help_magic;
|
||||
|
||||
/** next process in pipeline */
|
||||
struct process *next;
|
||||
struct process *next;
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/** Last time of cpu time check */
|
||||
struct timeval last_time;
|
||||
/** Number of jiffies spent in process at last cpu time check */
|
||||
unsigned long last_jiffies;
|
||||
unsigned long last_jiffies;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
process_t;
|
||||
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
true if user was told about stopped job
|
||||
true if user was told about stopped job
|
||||
*/
|
||||
#define JOB_NOTIFIED 1
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Whether this job is in the foreground
|
||||
Whether this job is in the foreground
|
||||
*/
|
||||
#define JOB_FOREGROUND 2
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Whether the specified job is completely constructed,
|
||||
|
@ -196,130 +196,130 @@ typedef struct process
|
|||
Whether the specified job is a part of a subshell, event handler or some other form of special job that should not be reported
|
||||
*/
|
||||
#define JOB_SKIP_NOTIFICATION 8
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Should the exit status be negated? This flag can only be set by the not builtin.
|
||||
Should the exit status be negated? This flag can only be set by the not builtin.
|
||||
*/
|
||||
#define JOB_NEGATE 16
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
This flag is set to one on wildcard expansion errors. It means that the current command should not be executed
|
||||
This flag is set to one on wildcard expansion errors. It means that the current command should not be executed
|
||||
*/
|
||||
#define JOB_WILDCARD_ERROR 32
|
||||
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or
|
||||
Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or
|
||||
*/
|
||||
#define JOB_SKIP 64
|
||||
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Whether the job is under job control
|
||||
Whether the job is under job control
|
||||
*/
|
||||
#define JOB_CONTROL 128
|
||||
/**
|
||||
/**
|
||||
Constant for the flag variable in the job struct
|
||||
|
||||
Whether the job wants to own the terminal when in the foreground
|
||||
Whether the job wants to own the terminal when in the foreground
|
||||
*/
|
||||
#define JOB_TERMINAL 256
|
||||
|
||||
/**
|
||||
/**
|
||||
A struct represeting a job. A job is basically a pipeline of one
|
||||
or more processes and a couple of flags.
|
||||
*/
|
||||
typedef struct job
|
||||
{
|
||||
/**
|
||||
/**
|
||||
The original command which led to the creation of this
|
||||
job. It is used for displaying messages about job status
|
||||
on the terminal.
|
||||
*/
|
||||
wchar_t *command;
|
||||
|
||||
/**
|
||||
wchar_t *command;
|
||||
|
||||
/**
|
||||
A linked list of all the processes in this job.
|
||||
*/
|
||||
process_t *first_process;
|
||||
|
||||
/**
|
||||
process_t *first_process;
|
||||
|
||||
/**
|
||||
process group ID for the process group that this job is
|
||||
running in.
|
||||
running in.
|
||||
*/
|
||||
pid_t pgid;
|
||||
|
||||
/**
|
||||
pid_t pgid;
|
||||
|
||||
/**
|
||||
The saved terminal modes of this job. This needs to be
|
||||
saved so that we can restore the terminal to the same
|
||||
state after temporarily taking control over the terminal
|
||||
when a job stops.
|
||||
when a job stops.
|
||||
*/
|
||||
struct termios tmodes;
|
||||
|
||||
|
||||
/**
|
||||
The job id of the job. This is a small integer that is a
|
||||
unique identifier of the job within this shell, and is
|
||||
used e.g. in process expansion.
|
||||
*/
|
||||
int job_id;
|
||||
|
||||
|
||||
/**
|
||||
List of all IO redirections for this job
|
||||
List of all IO redirections for this job
|
||||
*/
|
||||
io_data_t *io;
|
||||
|
||||
/**
|
||||
A pointer to the next job in the job queue
|
||||
|
||||
/**
|
||||
A pointer to the next job in the job queue
|
||||
*/
|
||||
struct job *next;
|
||||
struct job *next;
|
||||
|
||||
/**
|
||||
Bitset containing information about the job. A combination of the JOB_* constants.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
job_t;
|
||||
|
||||
/**
|
||||
Whether we are running a subshell command
|
||||
/**
|
||||
Whether we are running a subshell command
|
||||
*/
|
||||
extern int is_subshell;
|
||||
|
||||
/**
|
||||
Whether we are running a block of commands
|
||||
/**
|
||||
Whether we are running a block of commands
|
||||
*/
|
||||
extern int is_block;
|
||||
|
||||
/**
|
||||
/**
|
||||
Whether we are reading from the keyboard right now
|
||||
*/
|
||||
extern int is_interactive;
|
||||
|
||||
/**
|
||||
/**
|
||||
Whether this shell is attached to the keyboard at all
|
||||
*/
|
||||
extern int is_interactive_session;
|
||||
|
||||
/**
|
||||
/**
|
||||
Whether we are a login shell
|
||||
*/
|
||||
extern int is_login;
|
||||
|
||||
/**
|
||||
/**
|
||||
Whether we are running an event handler
|
||||
*/
|
||||
extern int is_event;
|
||||
|
||||
/**
|
||||
Linked list of all living jobs
|
||||
/**
|
||||
Linked list of all living jobs
|
||||
*/
|
||||
extern job_t *first_job;
|
||||
extern job_t *first_job;
|
||||
|
||||
/**
|
||||
Whether a universal variable barrier roundtrip has already been
|
||||
|
@ -396,7 +396,7 @@ job_t *job_get(int id);
|
|||
job_t *job_get_from_pid(int pid);
|
||||
|
||||
/**
|
||||
Tests if the job is stopped
|
||||
Tests if the job is stopped
|
||||
*/
|
||||
int job_is_stopped( const job_t *j );
|
||||
|
||||
|
|
635
reader.cpp
635
reader.cpp
File diff suppressed because it is too large
Load diff
39
reader.h
39
reader.h
|
@ -1,4 +1,4 @@
|
|||
/** \file reader.h
|
||||
/** \file reader.h
|
||||
|
||||
Prototypes for functions for reading data from stdin and passing
|
||||
to the parser. If stdin is a keyboard, it supplies a killring,
|
||||
|
@ -46,7 +46,7 @@ wchar_t *reader_current_filename();
|
|||
|
||||
/**
|
||||
Push a new filename on the stack of read files
|
||||
|
||||
|
||||
\param fn The fileanme to push
|
||||
*/
|
||||
void reader_push_current_filename( const wchar_t *fn );
|
||||
|
@ -86,7 +86,7 @@ wchar_t *reader_get_buffer();
|
|||
\param b the new buffer value
|
||||
\param p the cursor position. If \c p is less than zero, the cursor is placed on the last character.
|
||||
*/
|
||||
void reader_set_buffer( wchar_t *b, int p );
|
||||
void reader_set_buffer( const wchar_t *b, int p );
|
||||
|
||||
/**
|
||||
Get the current cursor position in the command line. If interactive
|
||||
|
@ -108,9 +108,9 @@ int reader_interrupted();
|
|||
wchar_t *reader_readline();
|
||||
|
||||
/**
|
||||
Push a new reader environment.
|
||||
Push a new reader environment.
|
||||
*/
|
||||
void reader_push( wchar_t *name );
|
||||
void reader_push( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Return to previous reader environment
|
||||
|
@ -118,7 +118,7 @@ void reader_push( wchar_t *name );
|
|||
void reader_pop();
|
||||
|
||||
/**
|
||||
Specify function to use for finding possible tab completions. The function must take these arguments:
|
||||
Specify function to use for finding possible tab completions. The function must take these arguments:
|
||||
|
||||
- The command to be completed as a null terminated array of wchar_t
|
||||
- An array_list_t in which completions will be inserted.
|
||||
|
@ -126,14 +126,23 @@ void reader_pop();
|
|||
void reader_set_complete_function( void (*f)( const wchar_t *, array_list_t * ) );
|
||||
|
||||
/**
|
||||
Specify function for syntax highlighting. The function must take these arguments:
|
||||
<<<<<<< upstream
|
||||
=======
|
||||
The type of a highlight function.
|
||||
*/
|
||||
class env_vars;
|
||||
typedef void (*highlight_function_t)( const wchar_t *, int *, int, array_list_t *, const env_vars &vars );
|
||||
|
||||
- The command to be highlighted as a null terminated array of wchar_t
|
||||
- The color code of each character as an array of ints
|
||||
- The cursor position
|
||||
- An array_list_t used for storing error messages
|
||||
*/
|
||||
void reader_set_highlight_function( void (*f)( wchar_t *, int *, int, array_list_t * ) );
|
||||
/**
|
||||
>>>>>>> HEAD~2
|
||||
Specify function for syntax highlighting. The function must take these arguments:
|
||||
|
||||
- The command to be highlighted as a null terminated array of wchar_t
|
||||
- The color code of each character as an array of ints
|
||||
- The cursor position
|
||||
- An array_list_t used for storing error messages
|
||||
*/
|
||||
void reader_set_highlight_function( highlight_function_t );
|
||||
|
||||
/**
|
||||
Specify function for testing if the command buffer contains syntax
|
||||
|
@ -145,10 +154,10 @@ void reader_set_test_function( int (*f)( wchar_t * ) );
|
|||
Specify string of shell commands to be run in order to generate the
|
||||
prompt.
|
||||
*/
|
||||
void reader_set_prompt( wchar_t *prompt );
|
||||
void reader_set_prompt( const wchar_t *prompt );
|
||||
|
||||
/**
|
||||
Returns true if the shell is exiting, 0 otherwise.
|
||||
Returns true if the shell is exiting, 0 otherwise.
|
||||
*/
|
||||
int exit_status();
|
||||
|
||||
|
|
16
sanity.cpp
16
sanity.cpp
|
@ -49,27 +49,27 @@ int sanity_check()
|
|||
kill_sanity_check();
|
||||
if( !insane )
|
||||
proc_sanity_check();
|
||||
|
||||
|
||||
return insane;
|
||||
}
|
||||
|
||||
void validate_pointer( const void *ptr, const wchar_t *err, int null_ok )
|
||||
{
|
||||
|
||||
/*
|
||||
Test if the pointer data crosses a segment boundary.
|
||||
|
||||
/*
|
||||
Test if the pointer data crosses a segment boundary.
|
||||
*/
|
||||
|
||||
|
||||
if( (0x00000003l & (long)ptr) != 0 )
|
||||
{
|
||||
debug( 0, _(L"The pointer '%ls' is invalid"), err );
|
||||
sanity_lose();
|
||||
sanity_lose();
|
||||
}
|
||||
|
||||
|
||||
if((!null_ok) && (ptr==0))
|
||||
{
|
||||
debug( 0, _(L"The pointer '%ls' is null"), err );
|
||||
sanity_lose();
|
||||
sanity_lose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
sanity.h
2
sanity.h
|
@ -19,7 +19,7 @@ int sanity_check();
|
|||
|
||||
/**
|
||||
Try and determine if ptr is a valid pointer. If not, loose sanity.
|
||||
|
||||
|
||||
\param ptr The pointer to validate
|
||||
\param err A description of what the pointer refers to, for use in error messages
|
||||
\param null_ok Wheter the pointer is allowed to point to 0
|
||||
|
|
168
screen.cpp
168
screen.cpp
|
@ -97,7 +97,7 @@ static int next_tab_stop( int in )
|
|||
*/
|
||||
if( init_tabs <= 0 )
|
||||
init_tabs = 8;
|
||||
|
||||
|
||||
return ( (in/init_tabs)+1 )*init_tabs;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ static int calc_prompt_width( wchar_t *prompt )
|
|||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
|
||||
/*
|
||||
Detect these terminfo color escapes with parameter
|
||||
value 0..7, all of which don't move the cursor
|
||||
|
@ -192,14 +192,14 @@ static int calc_prompt_width( wchar_t *prompt )
|
|||
*/
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &prompt[j] ),
|
||||
try_sequence( esc2[l], &prompt[j] ));
|
||||
|
||||
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !found )
|
||||
{
|
||||
if( prompt[j+1] == L'k' )
|
||||
|
@ -227,10 +227,10 @@ static int calc_prompt_width( wchar_t *prompt )
|
|||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if( prompt[j] == L'\t' )
|
||||
{
|
||||
|
@ -337,9 +337,9 @@ static void s_check_status( screen_t *s)
|
|||
is our best bet that we are still on the same line, so we
|
||||
move to the beginning of the line, reset the modelled screen
|
||||
contents, and then set the modeled cursor y-pos to its
|
||||
earlier value.
|
||||
earlier value.
|
||||
*/
|
||||
|
||||
|
||||
int prev_line = s->actual_cursor[1];
|
||||
write_loop( 1, "\r", 1 );
|
||||
s_reset( s, 0 );
|
||||
|
@ -348,7 +348,7 @@ static void s_check_status( screen_t *s)
|
|||
}
|
||||
|
||||
/**
|
||||
Free all memory used by one line_t struct.
|
||||
Free all memory used by one line_t struct.
|
||||
*/
|
||||
static void free_line( void *l )
|
||||
{
|
||||
|
@ -370,7 +370,7 @@ static void s_reset_arr( array_list_t *l )
|
|||
void s_init( screen_t *s )
|
||||
{
|
||||
CHECK( s, );
|
||||
|
||||
|
||||
memset( s, 0, sizeof(screen_t));
|
||||
sb_init( &s->actual_prompt );
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ void s_destroy( screen_t *s )
|
|||
al_destroy( &s->actual );
|
||||
s_reset_arr( &s->desired );
|
||||
al_destroy( &s->desired );
|
||||
sb_destroy( &s->actual_prompt );
|
||||
sb_destroy( &s->actual_prompt );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -392,7 +392,7 @@ void s_destroy( screen_t *s )
|
|||
*/
|
||||
static line_t *s_create_line()
|
||||
{
|
||||
line_t *current = malloc( sizeof( line_t ));
|
||||
line_t *current = (line_t *)malloc( sizeof( line_t ));
|
||||
al_init( ¤t->text );
|
||||
al_init( ¤t->color );
|
||||
return current;
|
||||
|
@ -401,16 +401,16 @@ static line_t *s_create_line()
|
|||
/**
|
||||
Appends a character to the end of the line that the output cursor is
|
||||
on. This function automatically handles linebreaks and lines longer
|
||||
than the screen width.
|
||||
than the screen width.
|
||||
*/
|
||||
static void s_desired_append_char( screen_t *s,
|
||||
static void s_desired_append_char( screen_t *s,
|
||||
wchar_t b,
|
||||
int c,
|
||||
int c,
|
||||
int indent,
|
||||
int prompt_width )
|
||||
{
|
||||
int line_no = s->desired_cursor[1];
|
||||
|
||||
|
||||
switch( b )
|
||||
{
|
||||
case L'\n':
|
||||
|
@ -426,16 +426,16 @@ static void s_desired_append_char( screen_t *s,
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'\r':
|
||||
{
|
||||
line_t *current;
|
||||
current = (line_t *)al_get( &s->desired, line_no );
|
||||
al_truncate( ¤t->text, 0 );
|
||||
al_truncate( ¤t->color, 0 );
|
||||
al_truncate( ¤t->color, 0 );
|
||||
s->desired_cursor[0]=0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -444,9 +444,9 @@ static void s_desired_append_char( screen_t *s,
|
|||
int cw = wcwidth(b);
|
||||
int ew = wcwidth( ellipsis_char );
|
||||
int i;
|
||||
|
||||
|
||||
current = (line_t *)al_get( &s->desired, line_no );
|
||||
|
||||
|
||||
if( !current )
|
||||
{
|
||||
current = s_create_line();
|
||||
|
@ -461,7 +461,7 @@ static void s_desired_append_char( screen_t *s,
|
|||
{
|
||||
al_set_long( ¤t->text, s->desired_cursor[0], ellipsis_char );
|
||||
al_set_long( ¤t->color, s->desired_cursor[0], HIGHLIGHT_COMMENT );
|
||||
|
||||
|
||||
current = s_create_line();
|
||||
al_push( &s->desired, current );
|
||||
s->desired_cursor[1]++;
|
||||
|
@ -469,17 +469,17 @@ static void s_desired_append_char( screen_t *s,
|
|||
for( i=0; i < (prompt_width-ew); i++ )
|
||||
{
|
||||
s_desired_append_char( s, L' ', 0, indent, prompt_width );
|
||||
}
|
||||
}
|
||||
s_desired_append_char( s, ellipsis_char, HIGHLIGHT_COMMENT, indent, prompt_width );
|
||||
}
|
||||
|
||||
|
||||
al_set_long( ¤t->text, s->desired_cursor[0], b );
|
||||
al_set_long( ¤t->color, s->desired_cursor[0], c );
|
||||
s->desired_cursor[0]+= cw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -495,7 +495,7 @@ static int s_writeb( char c )
|
|||
Write the bytes needed to move screen cursor to the specified
|
||||
position to the specified buffer. The actual_cursor field of the
|
||||
specified screen_t will be updated.
|
||||
|
||||
|
||||
\param s the screen to operate on
|
||||
\param b the buffer to send the output escape codes to
|
||||
\param new_x the new x position
|
||||
|
@ -505,22 +505,22 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
{
|
||||
int i;
|
||||
int x_steps, y_steps;
|
||||
|
||||
|
||||
int (*writer_old)(char) = output_get_writer();
|
||||
|
||||
char *str;
|
||||
/*
|
||||
debug( 0, L"move from %d %d to %d %d",
|
||||
s->screen_cursor[0], s->screen_cursor[1],
|
||||
debug( 0, L"move from %d %d to %d %d",
|
||||
s->screen_cursor[0], s->screen_cursor[1],
|
||||
new_x, new_y );
|
||||
*/
|
||||
output_set_writer( &s_writeb );
|
||||
s_writeb_buffer = b;
|
||||
|
||||
|
||||
y_steps = new_y - s->actual_cursor[1];
|
||||
|
||||
if( y_steps > 0 && (strcmp( cursor_down, "\n")==0))
|
||||
{
|
||||
{
|
||||
/*
|
||||
This is very strange - it seems some (all?) consoles use a
|
||||
simple newline as the cursor down escape. This will of
|
||||
|
@ -530,7 +530,7 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
*/
|
||||
s->actual_cursor[0]=0;
|
||||
}
|
||||
|
||||
|
||||
if( y_steps < 0 )
|
||||
{
|
||||
str = cursor_up;
|
||||
|
@ -538,9 +538,9 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
else
|
||||
{
|
||||
str = cursor_down;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<abs(y_steps); i++)
|
||||
{
|
||||
writembs(str);
|
||||
|
@ -548,14 +548,14 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
|
||||
|
||||
x_steps = new_x - s->actual_cursor[0];
|
||||
|
||||
|
||||
if( x_steps && new_x == 0 )
|
||||
{
|
||||
char c = '\r';
|
||||
b_append( b, &c, 1 );
|
||||
x_steps = 0;
|
||||
}
|
||||
|
||||
|
||||
if( x_steps < 0 ){
|
||||
str = cursor_left;
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
{
|
||||
str = cursor_right;
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<abs(x_steps); i++)
|
||||
{
|
||||
writembs(str);
|
||||
|
@ -572,9 +572,9 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
|
||||
s->actual_cursor[0] = new_x;
|
||||
s->actual_cursor[1] = new_y;
|
||||
|
||||
|
||||
output_set_writer( writer_old );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -582,17 +582,17 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
|||
*/
|
||||
static void s_set_color( screen_t *s, buffer_t *b, int c )
|
||||
{
|
||||
|
||||
|
||||
int (*writer_old)(char) = output_get_writer();
|
||||
|
||||
output_set_writer( &s_writeb );
|
||||
s_writeb_buffer = b;
|
||||
|
||||
|
||||
set_color( highlight_get_color( c & 0xffff ),
|
||||
highlight_get_color( (c>>16)&0xffff ) );
|
||||
|
||||
|
||||
output_set_writer( writer_old );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -606,9 +606,9 @@ static void s_write_char( screen_t *s, buffer_t *b, wchar_t c )
|
|||
output_set_writer( &s_writeb );
|
||||
s_writeb_buffer = b;
|
||||
s->actual_cursor[0]+=wcwidth( c );
|
||||
|
||||
|
||||
writech( c );
|
||||
|
||||
|
||||
output_set_writer( writer_old );
|
||||
}
|
||||
|
||||
|
@ -624,7 +624,7 @@ static void s_write_mbs( buffer_t *b, char *s )
|
|||
s_writeb_buffer = b;
|
||||
|
||||
writembs( s );
|
||||
|
||||
|
||||
output_set_writer( writer_old );
|
||||
}
|
||||
|
||||
|
@ -640,7 +640,7 @@ static void s_write_str( buffer_t *b, wchar_t *s )
|
|||
s_writeb_buffer = b;
|
||||
|
||||
writestr( s );
|
||||
|
||||
|
||||
output_set_writer( writer_old );
|
||||
}
|
||||
|
||||
|
@ -657,10 +657,10 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
buffer_t output;
|
||||
|
||||
scr->need_clear = 0;
|
||||
|
||||
|
||||
b_init( &output );
|
||||
|
||||
|
||||
|
||||
if( scr->actual_width != screen_width )
|
||||
{
|
||||
need_clear = 1;
|
||||
|
@ -668,16 +668,16 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
scr->actual_width = screen_width;
|
||||
s_reset( scr, 0 );
|
||||
}
|
||||
|
||||
|
||||
if( wcscmp( prompt, (wchar_t *)scr->actual_prompt.buff ) )
|
||||
{
|
||||
s_move( scr, &output, 0, 0 );
|
||||
s_write_str( &output, prompt );
|
||||
sb_clear( &scr->actual_prompt );
|
||||
sb_append( &scr->actual_prompt, prompt );
|
||||
sb_append( &scr->actual_prompt, prompt );
|
||||
scr->actual_cursor[0] = prompt_width;
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i< al_get_count( &scr->desired ); i++ )
|
||||
{
|
||||
line_t *o_line = (line_t *)al_get( &scr->desired, i );
|
||||
|
@ -695,34 +695,34 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
al_truncate( &s_line->color, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !s_line )
|
||||
{
|
||||
s_line = s_create_line();
|
||||
al_push( &scr->actual, s_line );
|
||||
}
|
||||
|
||||
|
||||
for( j=start_pos; j<al_get_count( &o_line->text ); j++ )
|
||||
{
|
||||
wchar_t o = (wchar_t)(long)al_get( &o_line->text, j );
|
||||
int o_c = (int)(long)al_get( &o_line->color, j );
|
||||
|
||||
wchar_t o = (wchar_t)(intptr_t)al_get( &o_line->text, j );
|
||||
int o_c = (int)(intptr_t)al_get( &o_line->color, j );
|
||||
|
||||
|
||||
if( !o )
|
||||
continue;
|
||||
|
||||
|
||||
if( al_get_count( &s_line->text ) == j )
|
||||
{
|
||||
s_move( scr, &output, current_width, i );
|
||||
s_set_color( scr, &output, o_c );
|
||||
s_write_char( scr, &output, o );
|
||||
al_set_long( &s_line->text, j, o );
|
||||
al_set_long( &s_line->color, j, o_c );
|
||||
al_set_long( &s_line->color, j, o_c );
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t s = (wchar_t)(long)al_get( &s_line->text, j );
|
||||
int s_c = (int)(long)al_get( &s_line->color, j );
|
||||
wchar_t s = (wchar_t)(intptr_t)al_get( &s_line->text, j );
|
||||
int s_c = (int)(intptr_t)al_get( &s_line->color, j );
|
||||
if( o != s || o_c != s_c )
|
||||
{
|
||||
s_move( scr, &output, current_width, i );
|
||||
|
@ -732,7 +732,7 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
al_set_long( &s_line->color, current_width, o_c );
|
||||
for( k=1; k<wcwidth(o); k++ )
|
||||
al_set_long( &s_line->text, current_width+k, L'\0' );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
current_width += wcwidth( o );
|
||||
|
@ -744,7 +744,7 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
s_write_mbs( &output, clr_eol);
|
||||
al_truncate( &s_line->text, al_get_count( &o_line->text ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for( i=al_get_count( &scr->desired ); i< al_get_count( &scr->actual ); i++ )
|
||||
{
|
||||
|
@ -753,18 +753,18 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
s_write_mbs( &output, clr_eol);
|
||||
al_truncate( &s_line->text, 0 );
|
||||
}
|
||||
|
||||
|
||||
s_move( scr, &output, scr->desired_cursor[0], scr->desired_cursor[1] );
|
||||
|
||||
|
||||
s_set_color( scr, &output, 0xffffffff);
|
||||
|
||||
if( output.used )
|
||||
{
|
||||
write_loop( 1, output.buff, output.used );
|
||||
}
|
||||
|
||||
|
||||
b_destroy( &output );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -779,8 +779,8 @@ static int is_dumb()
|
|||
|
||||
void s_write( screen_t *s,
|
||||
wchar_t *prompt,
|
||||
wchar_t *b,
|
||||
int *c,
|
||||
wchar_t *b,
|
||||
int *c,
|
||||
int *indent,
|
||||
int cursor )
|
||||
{
|
||||
|
@ -792,7 +792,7 @@ void s_write( screen_t *s,
|
|||
|
||||
int max_line_width = 0;
|
||||
int current_line_width = 0;
|
||||
|
||||
|
||||
CHECK( s, );
|
||||
CHECK( prompt, );
|
||||
CHECK( b, );
|
||||
|
@ -807,17 +807,17 @@ void s_write( screen_t *s,
|
|||
{
|
||||
char *prompt_narrow = wcs2str( prompt );
|
||||
char *buffer_narrow = wcs2str( b );
|
||||
|
||||
|
||||
write_loop( 1, "\r", 1 );
|
||||
write_loop( 1, prompt_narrow, strlen( prompt_narrow ) );
|
||||
write_loop( 1, buffer_narrow, strlen( buffer_narrow ) );
|
||||
|
||||
free( prompt_narrow );
|
||||
free( buffer_narrow );
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
prompt_width = calc_prompt_width( prompt );
|
||||
screen_width = common_get_width();
|
||||
|
||||
|
@ -835,7 +835,7 @@ void s_write( screen_t *s,
|
|||
prompt = L"> ";
|
||||
prompt_width = 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Completely ignore impossibly small screens
|
||||
*/
|
||||
|
@ -883,26 +883,26 @@ void s_write( screen_t *s,
|
|||
s_desired_append_char( s, L' ', 0, 0, prompt_width );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for( i=0; b[i]; i++ )
|
||||
{
|
||||
int col = c[i];
|
||||
|
||||
|
||||
if( i == cursor )
|
||||
{
|
||||
col = 0;
|
||||
}
|
||||
|
||||
|
||||
if( i == cursor )
|
||||
{
|
||||
cursor_arr[0] = s->desired_cursor[0];
|
||||
cursor_arr[1] = s->desired_cursor[1];
|
||||
}
|
||||
|
||||
|
||||
s_desired_append_char( s, b[i], col, indent[i], prompt_width );
|
||||
|
||||
|
||||
if( i== cursor && s->desired_cursor[1] != cursor_arr[1] && b[i] != L'\n' )
|
||||
{
|
||||
/*
|
||||
|
@ -914,13 +914,13 @@ void s_write( screen_t *s,
|
|||
cursor_arr[0] = s->desired_cursor[0] - wcwidth(b[i]);
|
||||
cursor_arr[1] = s->desired_cursor[1];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if( i == cursor )
|
||||
{
|
||||
memcpy(cursor_arr, s->desired_cursor, sizeof(int)*2);
|
||||
}
|
||||
|
||||
|
||||
memcpy( s->desired_cursor, cursor_arr, sizeof(int)*2 );
|
||||
s_update( s, prompt );
|
||||
s_save_status( s );
|
||||
|
|
16
screen.h
16
screen.h
|
@ -43,7 +43,7 @@ typedef struct
|
|||
The actual width of the screen at the time of the last screen
|
||||
write.
|
||||
*/
|
||||
int actual_width;
|
||||
int actual_width;
|
||||
|
||||
/**
|
||||
This flag is set to true when there is reason to suspect that
|
||||
|
@ -52,7 +52,7 @@ typedef struct
|
|||
has to be sent to the terminal at the end of each line.
|
||||
*/
|
||||
int need_clear;
|
||||
|
||||
|
||||
/**
|
||||
These status buffers are used to check if any output has occurred
|
||||
other than from fish's main loop, in which case we need to redraw.
|
||||
|
@ -71,7 +71,7 @@ typedef struct
|
|||
The text contents of the line. Each element of the array
|
||||
represents on column of output. Because some characters are two
|
||||
columns wide, it is perfectly possible for some of the comumns
|
||||
to be empty.
|
||||
to be empty.
|
||||
*/
|
||||
array_list_t text;
|
||||
/**
|
||||
|
@ -98,20 +98,20 @@ void s_destroy( screen_t *s );
|
|||
order to render the desired output using as few terminal commands
|
||||
as possible.
|
||||
*/
|
||||
void s_write( screen_t *s,
|
||||
wchar_t *prompt,
|
||||
void s_write( screen_t *s,
|
||||
wchar_t *prompt,
|
||||
wchar_t *commandline,
|
||||
int *colors,
|
||||
int *colors,
|
||||
int *indent,
|
||||
int cursor_pos );
|
||||
|
||||
/**
|
||||
/**
|
||||
This function resets the screen buffers internal knowledge about
|
||||
the contents of the screen. Use this function when some other
|
||||
function than s_write has written to the screen.
|
||||
|
||||
\param s the screen to reset
|
||||
\param reset_cursor whether the line on which the curor has changed should be assumed to have changed. If \c reset_cursor is set to 0, the library will attempt to make sure that the screen area does not seem to move up or down on repaint.
|
||||
\param reset_cursor whether the line on which the curor has changed should be assumed to have changed. If \c reset_cursor is set to 0, the library will attempt to make sure that the screen area does not seem to move up or down on repaint.
|
||||
|
||||
If reset_cursor is incorreclt set to 0, this may result in screen
|
||||
contents being erased. If it is incorrectly set to one, it may
|
||||
|
|
|
@ -81,7 +81,7 @@ char *col[]=
|
|||
|
||||
int col_idx[]=
|
||||
{
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
|
@ -112,16 +112,16 @@ int translate_color( char *str )
|
|||
color = -1;
|
||||
for( i=0; i<COLORS; i++ )
|
||||
{
|
||||
|
||||
|
||||
if( strcasecmp( col[i], str ) == 0 )
|
||||
{
|
||||
color = col_idx[i];
|
||||
color = col_idx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return color;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void print_colors()
|
||||
|
@ -130,7 +130,7 @@ void print_colors()
|
|||
for( i=0; i<COLORS; i++ )
|
||||
{
|
||||
printf( "%s\n", col[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_locale_init()
|
||||
|
@ -138,7 +138,7 @@ static void check_locale_init()
|
|||
static int is_init = 0;
|
||||
if( is_init )
|
||||
return;
|
||||
|
||||
|
||||
is_init = 1;
|
||||
setlocale( LC_ALL, "" );
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
|
@ -154,100 +154,100 @@ int main( int argc, char **argv )
|
|||
int bold=0;
|
||||
int underline=0;
|
||||
char *bg_seq, *fg_seq;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
"background", required_argument, 0, 'b'
|
||||
"background", required_argument, 0, 'b'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"bold", no_argument, 0, 'o'
|
||||
"bold", no_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
"underline", no_argument, 0, 'u'
|
||||
"underline", no_argument, 0, 'u'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
"print-colors", no_argument, 0, 'c'
|
||||
"print-colors", no_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
|
||||
case 'b':
|
||||
bgcolor = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
exit(0);
|
||||
|
||||
case 'o':
|
||||
bold=1;
|
||||
break;
|
||||
|
||||
|
||||
case 'u':
|
||||
underline=1;
|
||||
break;
|
||||
|
||||
|
||||
case 'v':
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
exit( 0 );
|
||||
|
||||
case 'c':
|
||||
print_colors();
|
||||
exit(0);
|
||||
|
||||
|
||||
case '?':
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
switch( argc-optind)
|
||||
{
|
||||
case 0:
|
||||
// printf( "no fg\n" );
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
fgcolor=argv[optind];
|
||||
// printf( "fg %s\n", fgcolor );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
check_locale_init();
|
||||
printf( _("%s: Too many arguments\n"), SET_COLOR );
|
||||
|
@ -258,16 +258,16 @@ int main( int argc, char **argv )
|
|||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
|
||||
print_help( argv[0], 2 );
|
||||
print_help( argv[0], 2 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
fg = translate_color(fgcolor);
|
||||
if( fgcolor && (fg==-1))
|
||||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bg = translate_color(bgcolor);
|
||||
|
@ -275,14 +275,14 @@ int main( int argc, char **argv )
|
|||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
setupterm( 0, STDOUT_FILENO, 0);
|
||||
|
||||
fg_seq = set_a_foreground?set_a_foreground:set_foreground;
|
||||
bg_seq = set_a_background?set_a_background:set_background;
|
||||
|
||||
|
||||
|
||||
if( bold )
|
||||
{
|
||||
|
@ -302,8 +302,8 @@ int main( int argc, char **argv )
|
|||
{
|
||||
if( bg_seq )
|
||||
putp( tparm( bg_seq, 0) );
|
||||
putp( tparm(exit_attribute_mode) );
|
||||
}
|
||||
putp( tparm(exit_attribute_mode) );
|
||||
}
|
||||
}
|
||||
|
||||
if( fgcolor )
|
||||
|
@ -312,15 +312,15 @@ int main( int argc, char **argv )
|
|||
{
|
||||
if( fg_seq )
|
||||
putp( tparm( fg_seq, 0) );
|
||||
putp( tparm(exit_attribute_mode) );
|
||||
}
|
||||
putp( tparm(exit_attribute_mode) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fg_seq )
|
||||
putp( tparm( fg_seq, fg) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( bgcolor )
|
||||
{
|
||||
if( bg != 8 )
|
||||
|
|
94
signal.cpp
94
signal.cpp
|
@ -47,7 +47,7 @@ struct lookup_entry
|
|||
/**
|
||||
Signal description
|
||||
*/
|
||||
const wchar_t *desc;
|
||||
const wchar_t *desc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -64,7 +64,7 @@ static const struct lookup_entry lookup[] =
|
|||
{
|
||||
#ifdef SIGHUP
|
||||
{
|
||||
SIGHUP,
|
||||
SIGHUP,
|
||||
L"SIGHUP",
|
||||
N_( L"Terminal hung up" )
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGTRAP
|
||||
{
|
||||
SIGTRAP,
|
||||
SIGTRAP,
|
||||
L"SIGTRAP",
|
||||
N_( L"Trace or breakpoint trap" )
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGBUS
|
||||
{
|
||||
SIGBUS,
|
||||
SIGBUS,
|
||||
L"SIGBUS",
|
||||
N_( L"Misaligned address error" )
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGFPE
|
||||
{
|
||||
SIGFPE,
|
||||
SIGFPE,
|
||||
L"SIGFPE",
|
||||
N_( L"Floating point exception" )
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGKILL
|
||||
{
|
||||
SIGKILL,
|
||||
SIGKILL,
|
||||
L"SIGKILL",
|
||||
N_( L"Forced quit" )
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGSEGV
|
||||
{
|
||||
SIGSEGV,
|
||||
SIGSEGV,
|
||||
L"SIGSEGV",
|
||||
N_( L"Address boundary error" )
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGALRM
|
||||
{
|
||||
SIGALRM,
|
||||
SIGALRM,
|
||||
L"SIGALRM",
|
||||
N_( L"Timer expired" )
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGTTIN
|
||||
{
|
||||
SIGTTIN,
|
||||
SIGTTIN,
|
||||
L"SIGTTIN",
|
||||
N_( L"Stop from terminal input" )
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGURG
|
||||
{
|
||||
SIGURG,
|
||||
SIGURG,
|
||||
L"SIGURG",
|
||||
N_( L"Urgent socket condition" )
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
{
|
||||
SIGXFSZ,
|
||||
SIGXFSZ,
|
||||
L"SIGXFSZ",
|
||||
N_( L"File size limit exceeded" )
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGPWR
|
||||
{
|
||||
SIGPWR,
|
||||
SIGPWR,
|
||||
L"SIGPWR",
|
||||
N_( L"Power failure" )
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ static const struct lookup_entry lookup[] =
|
|||
#endif
|
||||
#ifdef SIGSYS
|
||||
{
|
||||
SIGSYS,
|
||||
SIGSYS,
|
||||
L"SIGSYS",
|
||||
N_( L"Bad system call" )
|
||||
}
|
||||
|
@ -359,15 +359,15 @@ static const struct lookup_entry lookup[] =
|
|||
|
||||
|
||||
/**
|
||||
Test if \c name is a string describing the signal named \c canonical.
|
||||
Test if \c name is a string describing the signal named \c canonical.
|
||||
*/
|
||||
static int match_signal_name( const wchar_t *canonical,
|
||||
static int match_signal_name( const wchar_t *canonical,
|
||||
const wchar_t *name )
|
||||
{
|
||||
if( wcsncasecmp( name, L"sig", 3 )==0)
|
||||
name +=3;
|
||||
|
||||
return wcscasecmp( canonical+3,name ) == 0;
|
||||
return wcscasecmp( canonical+3,name ) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,7 +375,7 @@ int wcs2sig( const wchar_t *str )
|
|||
{
|
||||
int i, res;
|
||||
wchar_t *end=0;
|
||||
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
if( match_signal_name( lookup[i].name, str) )
|
||||
|
@ -387,8 +387,8 @@ int wcs2sig( const wchar_t *str )
|
|||
res = wcstol( str, &end, 10 );
|
||||
if( !errno && res>=0 && !*end )
|
||||
return res;
|
||||
|
||||
return -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -435,7 +435,7 @@ static void default_handler(int signal, siginfo_t *info, void *context)
|
|||
|
||||
if( event_get( &e, 0 ) )
|
||||
{
|
||||
|
||||
|
||||
event_fire( &e );
|
||||
}
|
||||
}
|
||||
|
@ -445,8 +445,8 @@ static void default_handler(int signal, siginfo_t *info, void *context)
|
|||
*/
|
||||
static void handle_winch( int sig, siginfo_t *info, void *context )
|
||||
{
|
||||
common_handle_winch( sig );
|
||||
default_handler( sig, 0, 0 );
|
||||
common_handle_winch( sig );
|
||||
default_handler( sig, 0, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,16 +460,16 @@ static void handle_hup( int sig, siginfo_t *info, void *context )
|
|||
e.type=EVENT_SIGNAL;
|
||||
e.param1.signal = SIGHUP;
|
||||
e.function_name=0;
|
||||
|
||||
|
||||
if( event_get( &e, 0 ) )
|
||||
{
|
||||
default_handler( sig, 0, 0 );
|
||||
default_handler( sig, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
reader_exit( 1, 1 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -479,7 +479,7 @@ static void handle_hup( int sig, siginfo_t *info, void *context )
|
|||
static void handle_int( int sig, siginfo_t *info, void *context )
|
||||
{
|
||||
reader_handle_int( sig );
|
||||
default_handler( sig, info, context);
|
||||
default_handler( sig, info, context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -488,22 +488,22 @@ static void handle_int( int sig, siginfo_t *info, void *context )
|
|||
static void handle_chld( int sig, siginfo_t *info, void *context )
|
||||
{
|
||||
job_handle_signal( sig, info, context );
|
||||
default_handler( sig, info, context);
|
||||
default_handler( sig, info, context);
|
||||
}
|
||||
|
||||
void signal_reset_handlers()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
struct sigaction act;
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=0;
|
||||
act.sa_handler=SIG_DFL;
|
||||
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
sigaction( lookup[i].signal, &act, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -516,11 +516,11 @@ void signal_set_handlers()
|
|||
|
||||
if( is_interactive == -1 )
|
||||
return;
|
||||
|
||||
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=SA_SIGINFO;
|
||||
act.sa_sigaction = &default_handler;
|
||||
|
||||
|
||||
/*
|
||||
First reset everything to a use default_handler, a function
|
||||
whose sole action is to fire of an event
|
||||
|
@ -531,7 +531,7 @@ void signal_set_handlers()
|
|||
sigaction( SIGTTIN, &act, 0);
|
||||
sigaction( SIGTTOU, &act, 0);
|
||||
sigaction( SIGCHLD, &act, 0);
|
||||
|
||||
|
||||
/*
|
||||
Ignore sigpipe, it is generated if fishd dies, but we can
|
||||
recover.
|
||||
|
@ -544,9 +544,9 @@ void signal_set_handlers()
|
|||
Interactive mode. Ignore interactive signals. We are a
|
||||
shell, we know whats best for the user. ;-)
|
||||
*/
|
||||
|
||||
|
||||
act.sa_handler=SIG_IGN;
|
||||
|
||||
|
||||
sigaction( SIGINT, &act, 0);
|
||||
sigaction( SIGQUIT, &act, 0);
|
||||
sigaction( SIGTSTP, &act, 0);
|
||||
|
@ -568,7 +568,7 @@ void signal_set_handlers()
|
|||
wperror( L"sigaction" );
|
||||
FATAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
#ifdef SIGWINCH
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction= &handle_winch;
|
||||
|
@ -609,13 +609,13 @@ void signal_set_handlers()
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void signal_handle( int sig, int do_handle )
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
|
||||
/*
|
||||
These should always be handled
|
||||
*/
|
||||
|
@ -626,7 +626,7 @@ void signal_handle( int sig, int do_handle )
|
|||
(sig == SIGTTOU) ||
|
||||
(sig == SIGCHLD) )
|
||||
return;
|
||||
|
||||
|
||||
sigemptyset( &act.sa_mask );
|
||||
if( do_handle )
|
||||
{
|
||||
|
@ -638,27 +638,27 @@ void signal_handle( int sig, int do_handle )
|
|||
act.sa_flags = 0;
|
||||
act.sa_handler = SIG_DFL;
|
||||
}
|
||||
|
||||
|
||||
sigaction( sig, &act, 0);
|
||||
}
|
||||
|
||||
void signal_block()
|
||||
{
|
||||
sigset_t chldset;
|
||||
|
||||
sigset_t chldset;
|
||||
|
||||
if( !block_count )
|
||||
{
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_BLOCK, &chldset, 0);
|
||||
sigprocmask(SIG_BLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
|
||||
block_count++;
|
||||
// debug( 0, L"signal block level increased to %d", block_count );
|
||||
}
|
||||
|
||||
void signal_unblock()
|
||||
{
|
||||
sigset_t chldset;
|
||||
sigset_t chldset;
|
||||
|
||||
block_count--;
|
||||
|
||||
|
@ -668,11 +668,11 @@ void signal_unblock()
|
|||
bugreport();
|
||||
FATAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
if( !block_count )
|
||||
{
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
}
|
||||
// debug( 0, L"signal block level decreased to %d", block_count );
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ static int check_size( tokenizer *tok, size_t len )
|
|||
{
|
||||
wchar_t *tmp;
|
||||
tok->last_len = len +1;
|
||||
tmp = realloc( tok->last, sizeof(wchar_t)*tok->last_len );
|
||||
tmp = (wchar_t *)realloc( tok->last, sizeof(wchar_t)*tok->last_len );
|
||||
if( tmp == 0 )
|
||||
{
|
||||
wperror( L"realloc" );
|
||||
|
@ -143,7 +143,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
|||
void tok_destroy( tokenizer *tok )
|
||||
{
|
||||
CHECK( tok, );
|
||||
|
||||
|
||||
free( tok->last );
|
||||
if( tok->free_orig )
|
||||
free( tok->orig_buff );
|
||||
|
@ -153,14 +153,14 @@ int tok_last_type( tokenizer *tok )
|
|||
{
|
||||
CHECK( tok, TOK_ERROR );
|
||||
CHECK( tok->buff, TOK_ERROR );
|
||||
|
||||
|
||||
return tok->last_type;
|
||||
}
|
||||
|
||||
wchar_t *tok_last( tokenizer *tok )
|
||||
{
|
||||
CHECK( tok, 0 );
|
||||
|
||||
|
||||
return tok->last;
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ static void read_string( tokenizer *tok )
|
|||
{
|
||||
do_loop = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if( *tok->buff == L'\n' && mode == 0)
|
||||
|
@ -240,15 +240,15 @@ static void read_string( tokenizer *tok )
|
|||
do_loop = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
tok->buff++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
The modes are as follows:
|
||||
|
||||
|
||||
0: regular text
|
||||
1: inside of subshell
|
||||
2: inside of array brackets
|
||||
|
@ -266,18 +266,18 @@ static void read_string( tokenizer *tok )
|
|||
mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'[':
|
||||
{
|
||||
if( tok->buff != start )
|
||||
mode=2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'\'':
|
||||
case L'"':
|
||||
{
|
||||
|
||||
|
||||
const wchar_t *end = quote_end( tok->buff );
|
||||
tok->last_quote = *tok->buff;
|
||||
if( end )
|
||||
|
@ -287,7 +287,7 @@ static void read_string( tokenizer *tok )
|
|||
else
|
||||
{
|
||||
tok->buff += wcslen( tok->buff );
|
||||
|
||||
|
||||
if( (!tok->accept_unfinished) )
|
||||
{
|
||||
tok_error( tok, TOK_UNTERMINATED_QUOTE, QUOTE_ERROR );
|
||||
|
@ -332,7 +332,7 @@ static void read_string( tokenizer *tok )
|
|||
}
|
||||
do_loop = 0;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ static void read_redirect( tokenizer *tok, int fd )
|
|||
wchar_t tok_last_quote( tokenizer *tok )
|
||||
{
|
||||
CHECK( tok, 0 );
|
||||
|
||||
|
||||
return tok->last_quote;
|
||||
}
|
||||
|
||||
|
@ -520,7 +520,7 @@ void tok_next( tokenizer *tok )
|
|||
|
||||
CHECK( tok, );
|
||||
CHECK( tok->buff, );
|
||||
|
||||
|
||||
if( tok_last_type( tok ) == TOK_ERROR )
|
||||
{
|
||||
tok->has_next=0;
|
||||
|
@ -552,7 +552,7 @@ void tok_next( tokenizer *tok )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( *tok->buff == L'#')
|
||||
{
|
||||
|
@ -649,7 +649,7 @@ wchar_t *tok_first( const wchar_t *str )
|
|||
wchar_t *res=0;
|
||||
|
||||
CHECK( str, 0 );
|
||||
|
||||
|
||||
tok_init( &t, str, 0 );
|
||||
|
||||
switch( tok_last_type( &t ) )
|
||||
|
@ -670,7 +670,7 @@ wchar_t *tok_first( const wchar_t *str )
|
|||
int tok_get_pos( tokenizer *tok )
|
||||
{
|
||||
CHECK( tok, 0 );
|
||||
|
||||
|
||||
return tok->last_pos;
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ int tok_get_pos( tokenizer *tok )
|
|||
void tok_set_pos( tokenizer *tok, int pos )
|
||||
{
|
||||
CHECK( tok, );
|
||||
|
||||
|
||||
tok->buff = tok->orig_buff + pos;
|
||||
tok->has_next = 1;
|
||||
tok_next( tok );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/** \file tokenizer.h
|
||||
/** \file tokenizer.h
|
||||
|
||||
A specialized tokenizer for tokenizing the fish language. In the
|
||||
future, the tokenizer should be extended to support marks,
|
||||
|
@ -60,7 +60,7 @@ enum tokenizer_error
|
|||
|
||||
|
||||
/**
|
||||
The tokenizer struct.
|
||||
The tokenizer struct.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ typedef struct
|
|||
wchar_t *orig_buff;
|
||||
/** A pointer to the last token*/
|
||||
wchar_t *last;
|
||||
|
||||
|
||||
/** Type of last token*/
|
||||
int last_type;
|
||||
/** Length of last token*/
|
||||
|
@ -102,7 +102,7 @@ tokenizer;
|
|||
\param flags Flags to the tokenizer. Setting TOK_ACCEPT_UNFINISHED will cause the tokenizer
|
||||
to accept incomplete tokens, such as a subshell without a closing
|
||||
parenthesis, as a valid token. Setting TOK_SHOW_COMMENTS will return comments as tokens
|
||||
|
||||
|
||||
*/
|
||||
void tok_init( tokenizer *tok, const wchar_t *b, int flags );
|
||||
|
||||
|
|
192
util.cpp
192
util.cpp
|
@ -64,7 +64,7 @@
|
|||
} \
|
||||
oom_handler_internal( p ); \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
|
||||
void util_die_on_oom( void * p);
|
||||
|
@ -74,7 +74,7 @@ void (*oom_handler_internal)(void *) = &util_die_on_oom;
|
|||
void (*util_set_oom_handler( void (*h)(void *) ))(void *)
|
||||
{
|
||||
void (*old)(void *) = oom_handler_internal;
|
||||
|
||||
|
||||
if( h )
|
||||
oom_handler_internal = h;
|
||||
else
|
||||
|
@ -130,9 +130,9 @@ static int q_realloc( dyn_queue_t *q )
|
|||
void **old_stop = q->stop;
|
||||
int diff;
|
||||
int new_size;
|
||||
|
||||
|
||||
new_size = 2*(q->stop-q->start);
|
||||
|
||||
|
||||
q->start=(void**)realloc( q->start, sizeof(void*)*new_size );
|
||||
if( !q->start )
|
||||
{
|
||||
|
@ -140,13 +140,13 @@ static int q_realloc( dyn_queue_t *q )
|
|||
oom_handler( q );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
diff = q->start - old_start;
|
||||
q->get_pos += diff;
|
||||
q->stop = &q->start[new_size];
|
||||
memcpy( old_stop + diff, q->start, sizeof(void*)*(q->get_pos-q->start));
|
||||
q->put_pos = old_stop + diff + (q->get_pos-q->start);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ int q_put( dyn_queue_t *q, void *e )
|
|||
*q->put_pos = e;
|
||||
|
||||
// fprintf( stderr, "Put element %d to queue %d\n", e, q );
|
||||
|
||||
|
||||
if( ++q->put_pos == q->stop )
|
||||
q->put_pos = q->start;
|
||||
if( q->put_pos == q->get_pos )
|
||||
|
@ -175,7 +175,7 @@ void *q_peek( dyn_queue_t *q )
|
|||
{
|
||||
return *q->get_pos;
|
||||
}
|
||||
|
||||
|
||||
int q_empty( dyn_queue_t *q )
|
||||
{
|
||||
// fprintf( stderr, "Queue %d is %s\n", q, (q->put_pos == q->get_pos)?"empty":"non-empty" );
|
||||
|
@ -199,15 +199,15 @@ void hash_init2( hash_table_t *h,
|
|||
reasonably good size with regard to avoiding patterns of collisions.
|
||||
*/
|
||||
sz--;
|
||||
|
||||
|
||||
|
||||
h->arr = malloc( sizeof(hash_struct_t)*sz );
|
||||
h->arr = (hash_struct_t *)malloc( sizeof(hash_struct_t)*sz );
|
||||
if( !h->arr )
|
||||
{
|
||||
oom_handler( h );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
h->size = sz;
|
||||
for( i=0; i< sz; i++ )
|
||||
h->arr[i].key = 0;
|
||||
|
@ -279,14 +279,14 @@ static int hash_realloc( hash_table_t *h,
|
|||
if( ( sz < h->size ) && (h->size < HASH_MIN_SIZE))
|
||||
return 1;
|
||||
sz = maxi( sz, HASH_MIN_SIZE );
|
||||
|
||||
|
||||
hash_struct_t *old_arr = h->arr;
|
||||
int old_size = h->size;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
h->cache = -1;
|
||||
h->arr = malloc( sizeof( hash_struct_t) * sz );
|
||||
h->arr = (hash_struct_t *)malloc( sizeof( hash_struct_t) * sz );
|
||||
if( h->arr == 0 )
|
||||
{
|
||||
h->arr = old_arr;
|
||||
|
@ -319,7 +319,7 @@ int hash_put( hash_table_t *h,
|
|||
const void *data )
|
||||
{
|
||||
int pos;
|
||||
|
||||
|
||||
if( (float)(h->count+1)/h->size > 0.75f )
|
||||
{
|
||||
if( !hash_realloc( h, (h->size+1) * 2 -1 ) )
|
||||
|
@ -345,8 +345,8 @@ void *hash_get( hash_table_t *h,
|
|||
{
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
int pos = hash_search( h, (void *)key );
|
||||
|
||||
int pos = hash_search( h, (void *)key );
|
||||
if( h->arr[pos].key == 0 )
|
||||
{
|
||||
return 0;
|
||||
|
@ -360,10 +360,10 @@ void *hash_get( hash_table_t *h,
|
|||
|
||||
void *hash_get_key( hash_table_t *h,
|
||||
const void *key )
|
||||
{
|
||||
{
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
|
||||
int pos = hash_search( h, (void *)key );
|
||||
if( h->arr[pos].key == 0 )
|
||||
return 0;
|
||||
|
@ -449,7 +449,7 @@ int hash_contains( hash_table_t *h,
|
|||
{
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
|
||||
int pos = hash_search( h, (void *)key );
|
||||
return h->arr[pos].key != 0;
|
||||
}
|
||||
|
@ -541,7 +541,7 @@ static unsigned int rotl30( unsigned int in )
|
|||
|
||||
/**
|
||||
The number of words of input used in each lap by the sha-like
|
||||
string hashing algorithm.
|
||||
string hashing algorithm.
|
||||
*/
|
||||
#define WORD_COUNT 16
|
||||
|
||||
|
@ -550,11 +550,11 @@ int hash_wcs_func( void *data )
|
|||
const wchar_t *in = (const wchar_t *)data;
|
||||
unsigned int a,b,c,d,e;
|
||||
int t;
|
||||
unsigned int k0=0x5a827999u;
|
||||
unsigned int k0=0x5a827999u;
|
||||
unsigned int k1 =0x6ed9eba1u;
|
||||
|
||||
unsigned int w[2*WORD_COUNT];
|
||||
|
||||
|
||||
unsigned int w[2*WORD_COUNT];
|
||||
|
||||
/*
|
||||
Same constants used by sha1
|
||||
*/
|
||||
|
@ -563,10 +563,10 @@ int hash_wcs_func( void *data )
|
|||
c=0x98badcfeu;
|
||||
d=0x10325476u;
|
||||
e=0xc3d2e1f0u;
|
||||
|
||||
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
while( *in )
|
||||
{
|
||||
int i;
|
||||
|
@ -586,9 +586,9 @@ int hash_wcs_func( void *data )
|
|||
}
|
||||
else
|
||||
w[i]=*in++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
And fill up the rest by rotating the previous content
|
||||
*/
|
||||
|
@ -642,11 +642,11 @@ int hash_str_cmp( void *a, void *b )
|
|||
int hash_str_func( void *data )
|
||||
{
|
||||
int res = 0x67452301u;
|
||||
const char *str = data;
|
||||
const char *str = (const char *)data;
|
||||
|
||||
while( *str )
|
||||
res = (18499*rotl5(res)) ^ *str++;
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -773,7 +773,7 @@ void pq_destroy( priority_queue_t *q )
|
|||
|
||||
array_list_t *al_new()
|
||||
{
|
||||
array_list_t *res = malloc( sizeof( array_list_t ) );
|
||||
array_list_t *res = (array_list_t *)malloc( sizeof( array_list_t ) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
|
@ -811,8 +811,8 @@ static int al_push_generic( array_list_t *l, anything_t o )
|
|||
oom_handler( l );
|
||||
return 0;
|
||||
}
|
||||
l->arr = tmp;
|
||||
l->size = new_size;
|
||||
l->arr = (anything_t *)tmp;
|
||||
l->size = new_size;
|
||||
}
|
||||
l->arr[l->pos++] = o;
|
||||
return 1;
|
||||
|
@ -857,10 +857,10 @@ int al_insert( array_list_t *a, int pos, int count )
|
|||
assert( pos >= 0 );
|
||||
assert( count >= 0 );
|
||||
assert( a );
|
||||
|
||||
|
||||
if( !count )
|
||||
return 0;
|
||||
|
||||
|
||||
/*
|
||||
Reallocate, if needed
|
||||
*/
|
||||
|
@ -870,30 +870,30 @@ int al_insert( array_list_t *a, int pos, int count )
|
|||
If we reallocate, add a few extra elements just in case we
|
||||
want to do some more reallocating any time soon
|
||||
*/
|
||||
size_t new_size = maxi( maxi( pos, a->pos ) + count +32, a->size*2);
|
||||
size_t new_size = maxi( maxi( pos, a->pos ) + count +32, a->size*2);
|
||||
void *tmp = realloc( a->arr, sizeof( anything_t )*new_size );
|
||||
if( tmp )
|
||||
{
|
||||
a->arr = tmp;
|
||||
a->arr = (anything_t *)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
oom_handler( a );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( a->pos > pos )
|
||||
{
|
||||
memmove( &a->arr[pos],
|
||||
&a->arr[pos+count],
|
||||
&a->arr[pos+count],
|
||||
sizeof(anything_t ) * (a->pos-pos) );
|
||||
}
|
||||
|
||||
|
||||
memset( &a->arr[pos], 0, sizeof(anything_t)*count );
|
||||
a->pos += count;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,7 @@ int al_insert( array_list_t *a, int pos, int count )
|
|||
static int al_set_generic( array_list_t *l, int pos, anything_t v )
|
||||
{
|
||||
int old_pos;
|
||||
|
||||
|
||||
if( pos < 0 )
|
||||
return 0;
|
||||
if( pos < l->pos )
|
||||
|
@ -914,16 +914,16 @@ static int al_set_generic( array_list_t *l, int pos, anything_t v )
|
|||
return 1;
|
||||
}
|
||||
old_pos=l->pos;
|
||||
|
||||
|
||||
l->pos = pos;
|
||||
if( al_push_generic( l, v ) )
|
||||
{
|
||||
memset( &l->arr[old_pos],
|
||||
memset( &l->arr[old_pos],
|
||||
0,
|
||||
sizeof(anything_t) * (pos - old_pos) );
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int al_set( array_list_t *l, int pos, const void *o )
|
||||
|
@ -954,7 +954,7 @@ static anything_t al_get_generic( array_list_t *l, int pos )
|
|||
{
|
||||
anything_t res;
|
||||
res.ptr_val=0;
|
||||
|
||||
|
||||
if( (pos >= 0) && (pos < l->pos) )
|
||||
res = l->arr[pos];
|
||||
|
||||
|
@ -997,15 +997,15 @@ static anything_t al_pop_generic( array_list_t *l )
|
|||
memset( &e, 0, sizeof(anything_t ) );
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
e = l->arr[--l->pos];
|
||||
if( (l->pos*3 < l->size) && (l->size < MIN_SIZE) )
|
||||
{
|
||||
anything_t *old_arr = l->arr;
|
||||
int old_size = l->size;
|
||||
l->size = l->size/2;
|
||||
l->arr = realloc( l->arr, sizeof(anything_t)*l->size );
|
||||
l->arr = (anything_t *)realloc( l->arr, sizeof(anything_t)*l->size );
|
||||
if( l->arr == 0 )
|
||||
{
|
||||
l->arr = old_arr;
|
||||
|
@ -1022,17 +1022,17 @@ static anything_t al_pop_generic( array_list_t *l )
|
|||
|
||||
void *al_pop( array_list_t *l )
|
||||
{
|
||||
return al_pop_generic(l).ptr_val;
|
||||
return al_pop_generic(l).ptr_val;
|
||||
}
|
||||
|
||||
long al_pop_long( array_list_t *l )
|
||||
{
|
||||
return al_pop_generic(l).long_val;
|
||||
return al_pop_generic(l).long_val;
|
||||
}
|
||||
|
||||
func_ptr_t al_pop_func( array_list_t *l )
|
||||
{
|
||||
return al_pop_generic(l).func_val;
|
||||
return al_pop_generic(l).func_val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1050,17 +1050,17 @@ static anything_t al_peek_generic( array_list_t *l )
|
|||
|
||||
void *al_peek( array_list_t *l )
|
||||
{
|
||||
return al_peek_generic(l).ptr_val;
|
||||
return al_peek_generic(l).ptr_val;
|
||||
}
|
||||
|
||||
long al_peek_long( array_list_t *l )
|
||||
{
|
||||
return al_peek_generic(l).long_val;
|
||||
return al_peek_generic(l).long_val;
|
||||
}
|
||||
|
||||
func_ptr_t al_peek_func( array_list_t *l )
|
||||
{
|
||||
return al_peek_generic(l).func_val;
|
||||
return al_peek_generic(l).func_val;
|
||||
}
|
||||
|
||||
int al_empty( array_list_t *l )
|
||||
|
@ -1093,7 +1093,7 @@ void al_foreach2( array_list_t *l, void (*func)( void *, void *), void *aux)
|
|||
|
||||
CHECK( l, );
|
||||
CHECK( func, );
|
||||
|
||||
|
||||
for( i=0; i<l->pos; i++ )
|
||||
func( l->arr[i].ptr_val, aux );
|
||||
}
|
||||
|
@ -1102,7 +1102,7 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
|||
{
|
||||
CHECK( a, 0 );
|
||||
CHECK( b, 0 );
|
||||
|
||||
|
||||
if( *a==0 )
|
||||
{
|
||||
if( *b==0)
|
||||
|
@ -1122,7 +1122,7 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
|||
long bl;
|
||||
int diff;
|
||||
|
||||
errno = 0;
|
||||
errno = 0;
|
||||
al = wcstol( a, &aend, 10 );
|
||||
bl = wcstol( b, &bend, 10 );
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
|||
*/
|
||||
return wcscmp( a, b );
|
||||
}
|
||||
|
||||
|
||||
diff = al - bl;
|
||||
if( diff )
|
||||
return diff>0?2:-2;
|
||||
|
@ -1165,9 +1165,9 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
|||
return secondary_diff>0?1:-1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void sb_init( string_buffer_t * b)
|
||||
|
@ -1181,21 +1181,21 @@ void sb_init( string_buffer_t * b)
|
|||
return;
|
||||
}
|
||||
|
||||
memset( b, 0, sizeof(string_buffer_t) );
|
||||
memset( b, 0, sizeof(string_buffer_t) );
|
||||
b_append( b, &c, sizeof( wchar_t));
|
||||
b->used -= sizeof(wchar_t);
|
||||
}
|
||||
|
||||
string_buffer_t *sb_new()
|
||||
{
|
||||
string_buffer_t *res = malloc( sizeof( string_buffer_t ) );
|
||||
string_buffer_t *res = (string_buffer_t *)malloc( sizeof( string_buffer_t ) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
oom_handler( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sb_init( res );
|
||||
return res;
|
||||
}
|
||||
|
@ -1230,7 +1230,7 @@ void sb_append_internal( string_buffer_t *b, ... )
|
|||
wchar_t *arg;
|
||||
|
||||
CHECK( b, );
|
||||
|
||||
|
||||
va_start( va, b );
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
{
|
||||
|
@ -1244,47 +1244,47 @@ int sb_printf( string_buffer_t *buffer, const wchar_t *format, ... )
|
|||
{
|
||||
va_list va;
|
||||
int res;
|
||||
|
||||
|
||||
CHECK( buffer, -1 );
|
||||
CHECK( format, -1 );
|
||||
|
||||
|
||||
va_start( va, format );
|
||||
res = sb_vprintf( buffer, format, va );
|
||||
res = sb_vprintf( buffer, format, va );
|
||||
va_end( va );
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig )
|
||||
{
|
||||
int res;
|
||||
|
||||
|
||||
CHECK( buffer, -1 );
|
||||
CHECK( format, -1 );
|
||||
|
||||
if( !buffer->length )
|
||||
{
|
||||
buffer->length = MIN_SIZE;
|
||||
buffer->buff = malloc( MIN_SIZE );
|
||||
buffer->buff = (char *)malloc( MIN_SIZE );
|
||||
if( !buffer->buff )
|
||||
{
|
||||
oom_handler( buffer );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
va_list va;
|
||||
va_copy( va, va_orig );
|
||||
|
||||
res = vswprintf( (wchar_t *)((char *)buffer->buff+buffer->used),
|
||||
(buffer->length-buffer->used)/sizeof(wchar_t),
|
||||
|
||||
res = vswprintf( (wchar_t *)((char *)buffer->buff+buffer->used),
|
||||
(buffer->length-buffer->used)/sizeof(wchar_t),
|
||||
format,
|
||||
va );
|
||||
|
||||
|
||||
|
||||
va_end( va );
|
||||
va_end( va );
|
||||
if( res >= 0 )
|
||||
{
|
||||
buffer->used+= res*sizeof(wchar_t);
|
||||
|
@ -1295,7 +1295,7 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
|||
As far as I know, there is no way to check if a
|
||||
vswprintf-call failed because of a badly formated string
|
||||
option or because the supplied destination string was to
|
||||
small. In GLIBC, errno seems to be set to EINVAL either way.
|
||||
small. In GLIBC, errno seems to be set to EINVAL either way.
|
||||
|
||||
Because of this, sb_printf will on failiure try to
|
||||
increase the buffer size until the free space is
|
||||
|
@ -1304,7 +1304,7 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
|||
formated string option, and return an error. Make
|
||||
sure to null terminate string before that, though.
|
||||
*/
|
||||
|
||||
|
||||
if( buffer->length - buffer->used > SB_MAX_SIZE )
|
||||
{
|
||||
wchar_t tmp=0;
|
||||
|
@ -1312,18 +1312,18 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
|||
buffer->used -= sizeof(wchar_t);
|
||||
break;
|
||||
}
|
||||
|
||||
buffer->buff = realloc( buffer->buff, 2*buffer->length );
|
||||
|
||||
buffer->buff = (char *)realloc( buffer->buff, 2*buffer->length );
|
||||
|
||||
if( !buffer->buff )
|
||||
{
|
||||
oom_handler( buffer );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer->length *= 2;
|
||||
|
||||
buffer->length *= 2;
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1332,7 +1332,7 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
|||
void sb_destroy( string_buffer_t * b )
|
||||
{
|
||||
CHECK( b, );
|
||||
|
||||
|
||||
free( b->buff );
|
||||
}
|
||||
|
||||
|
@ -1345,20 +1345,20 @@ void sb_clear( string_buffer_t * b )
|
|||
void sb_truncate( string_buffer_t *b, int chars_left )
|
||||
{
|
||||
wchar_t *arr;
|
||||
|
||||
|
||||
CHECK( b, );
|
||||
|
||||
b->used = (chars_left)*sizeof( wchar_t);
|
||||
arr = (wchar_t *)b->buff;
|
||||
arr[chars_left] = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
ssize_t sb_length( string_buffer_t *b )
|
||||
{
|
||||
CHECK( b, -1 );
|
||||
return (b->used-1)/sizeof( wchar_t);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1384,7 +1384,7 @@ int b_append( buffer_t *b, const void *d, ssize_t len )
|
|||
if( len<=0 )
|
||||
return 0;
|
||||
|
||||
CHECK( b, -1 );
|
||||
CHECK( b, -1 );
|
||||
|
||||
if( !b )
|
||||
{
|
||||
|
@ -1400,14 +1400,14 @@ int b_append( buffer_t *b, const void *d, ssize_t len )
|
|||
{
|
||||
size_t l = maxi( b->length*2,
|
||||
b->used+len+MIN_SIZE );
|
||||
|
||||
|
||||
void *d = realloc( b->buff, l );
|
||||
if( !d )
|
||||
{
|
||||
oom_handler( b );
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
b->buff=d;
|
||||
b->buff=(char *)d;
|
||||
b->length = l;
|
||||
}
|
||||
memcpy( ((char*)b->buff)+b->used,
|
||||
|
|
104
util.h
104
util.h
|
@ -25,7 +25,7 @@ typedef void (*func_ptr_t)();
|
|||
used to make sure that the pointer type can fit whatever we want to
|
||||
insert.
|
||||
*/
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
/**
|
||||
long value
|
||||
|
@ -91,7 +91,7 @@ typedef struct hash_table
|
|||
/** The array containing the data */
|
||||
hash_struct_t *arr;
|
||||
/** A simple one item cache. This should always point to the index of the last item to be used */
|
||||
int cache;
|
||||
int cache;
|
||||
/** Number of elements */
|
||||
int count;
|
||||
/** Length of array */
|
||||
|
@ -128,12 +128,12 @@ priority_queue_t;
|
|||
*/
|
||||
typedef struct array_list
|
||||
{
|
||||
/**
|
||||
/**
|
||||
Array containing the data
|
||||
*/
|
||||
anything_t *arr;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
Internal cursor position of the array_list_t. This is the
|
||||
position to append elements at. This is also what the
|
||||
array_list_t considers to be its true size, as reported by
|
||||
|
@ -142,7 +142,7 @@ typedef struct array_list
|
|||
*/
|
||||
size_t pos;
|
||||
|
||||
/**
|
||||
/**
|
||||
Amount of memory allocated in arr, expressed in number of elements.
|
||||
*/
|
||||
size_t size;
|
||||
|
@ -181,8 +181,8 @@ typedef buffer_t string_buffer_t;
|
|||
|
||||
/**
|
||||
Set the out-of-memory handler callback function. If a memory
|
||||
allocation fails, this function will be called.
|
||||
*/
|
||||
allocation fails, this function will be called.
|
||||
*/
|
||||
void (*util_set_oom_handler( void (*h)(void *) ))(void *);
|
||||
|
||||
/**
|
||||
|
@ -207,38 +207,38 @@ int mini( int a, int b );
|
|||
/*
|
||||
All the datastuctures below autoresize. The queue, stack and
|
||||
priority queue are all impemented using an array and are guaranteed
|
||||
to never be less than 50% full.
|
||||
to never be less than 50% full.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
Initialize the queue. A queue is a FIFO buffer, i.e. the first
|
||||
element to be inserted into the buffer is the first element to be
|
||||
returned.
|
||||
returned.
|
||||
*/
|
||||
void q_init( dyn_queue_t *q );
|
||||
|
||||
/**
|
||||
Destroy the queue
|
||||
Destroy the queue
|
||||
*/
|
||||
void q_destroy( dyn_queue_t *q );
|
||||
|
||||
/**
|
||||
Insert element into queue
|
||||
Insert element into queue
|
||||
*/
|
||||
int q_put( dyn_queue_t *q, void *e );
|
||||
|
||||
/**
|
||||
Remove and return next element from queue
|
||||
Remove and return next element from queue
|
||||
*/
|
||||
void *q_get( dyn_queue_t *q);
|
||||
|
||||
/**
|
||||
Return next element from queue without removing it
|
||||
Return next element from queue without removing it
|
||||
*/
|
||||
void *q_peek( dyn_queue_t *q);
|
||||
|
||||
/**
|
||||
Returns 1 if the queue is empty, 0 otherwise
|
||||
Returns 1 if the queue is empty, 0 otherwise
|
||||
*/
|
||||
int q_empty( dyn_queue_t *q );
|
||||
|
||||
|
@ -262,9 +262,9 @@ void hash_init2( hash_table_t *h,
|
|||
*/
|
||||
void hash_destroy( hash_table_t *h );
|
||||
/**
|
||||
Set the key/value pair for the hashtable.
|
||||
Set the key/value pair for the hashtable.
|
||||
*/
|
||||
int hash_put( hash_table_t *h,
|
||||
int hash_put( hash_table_t *h,
|
||||
const void *key,
|
||||
const void *data );
|
||||
/**
|
||||
|
@ -275,7 +275,7 @@ void *hash_get( hash_table_t *h,
|
|||
/**
|
||||
Returns the hash tables version of the specified key
|
||||
*/
|
||||
void *hash_get_key( hash_table_t *h,
|
||||
void *hash_get_key( hash_table_t *h,
|
||||
const void *key );
|
||||
|
||||
/**
|
||||
|
@ -290,15 +290,15 @@ int hash_get_count( hash_table_t *h);
|
|||
\param old_key If not 0, a pointer to the old key will be stored at the specified address
|
||||
\param old_data If not 0, a pointer to the data will be stored at the specified address
|
||||
*/
|
||||
void hash_remove( hash_table_t *h,
|
||||
const void *key,
|
||||
void hash_remove( hash_table_t *h,
|
||||
const void *key,
|
||||
void **old_key,
|
||||
void **old_data );
|
||||
|
||||
/**
|
||||
Checks whether the specified key is in the hash table
|
||||
*/
|
||||
int hash_contains( hash_table_t *h,
|
||||
int hash_contains( hash_table_t *h,
|
||||
const void *key );
|
||||
|
||||
/**
|
||||
|
@ -316,20 +316,20 @@ void hash_get_data( hash_table_t *h,
|
|||
/**
|
||||
Call the function func for each key/data pair in the table
|
||||
*/
|
||||
void hash_foreach( hash_table_t *h,
|
||||
void hash_foreach( hash_table_t *h,
|
||||
void (*func)( void *, void * ) );
|
||||
|
||||
/**
|
||||
Same as hash_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
argument, which is provided by the caller in the variable aux
|
||||
*/
|
||||
void hash_foreach2( hash_table_t *h, void (*func)( void *,
|
||||
void *,
|
||||
void *),
|
||||
void hash_foreach2( hash_table_t *h, void (*func)( void *,
|
||||
void *,
|
||||
void *),
|
||||
void *aux );
|
||||
|
||||
/**
|
||||
Hash function suitable for character strings.
|
||||
Hash function suitable for character strings.
|
||||
*/
|
||||
int hash_str_func( void *data );
|
||||
/**
|
||||
|
@ -348,7 +348,7 @@ int hash_wcs_func( void *data );
|
|||
/**
|
||||
Hash comparison function suitable for wide character strings
|
||||
*/
|
||||
int hash_wcs_cmp( void *a,
|
||||
int hash_wcs_cmp( void *a,
|
||||
void *b );
|
||||
|
||||
/**
|
||||
|
@ -365,9 +365,9 @@ int hash_ptr_cmp( void *a,
|
|||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Initialize the priority queue
|
||||
|
||||
|
||||
\param q the queue to initialize
|
||||
\param compare a comparison function that can compare two entries in the queue
|
||||
*/
|
||||
|
@ -378,7 +378,7 @@ void pq_init( priority_queue_t *q,
|
|||
|
||||
\param q the queue
|
||||
\param e the new element
|
||||
|
||||
|
||||
*/
|
||||
int pq_put( priority_queue_t *q,
|
||||
void *e );
|
||||
|
@ -392,7 +392,7 @@ void *pq_get( priority_queue_t *q );
|
|||
*/
|
||||
void *pq_peek( priority_queue_t *q );
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns 1 if the priority queue is empty, 0 otherwise.
|
||||
*/
|
||||
int pq_empty( priority_queue_t *q );
|
||||
|
@ -402,7 +402,7 @@ int pq_empty( priority_queue_t *q );
|
|||
*/
|
||||
int pq_get_count( priority_queue_t *q );
|
||||
|
||||
/**
|
||||
/**
|
||||
Destroy the priority queue and free memory used by it.
|
||||
*/
|
||||
void pq_destroy( priority_queue_t *q );
|
||||
|
@ -413,12 +413,12 @@ void pq_destroy( priority_queue_t *q );
|
|||
*/
|
||||
array_list_t *al_new();
|
||||
|
||||
/**
|
||||
Initialize the list.
|
||||
/**
|
||||
Initialize the list.
|
||||
*/
|
||||
void al_init( array_list_t *l );
|
||||
|
||||
/**
|
||||
/**
|
||||
Destroy the list and free memory used by it.
|
||||
*/
|
||||
void al_destroy( array_list_t *l );
|
||||
|
@ -468,15 +468,15 @@ int al_insert( array_list_t *a, int pos, int count );
|
|||
Sets the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\param o The element
|
||||
\param pos The index
|
||||
\param o The element
|
||||
*/
|
||||
int al_set( array_list_t *l, int pos, const void *o );
|
||||
/**
|
||||
Sets the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\param pos The index
|
||||
\param v The element to set
|
||||
*/
|
||||
int al_set_long( array_list_t *l, int pos, long v );
|
||||
|
@ -484,7 +484,7 @@ int al_set_long( array_list_t *l, int pos, long v );
|
|||
Sets the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\param pos The index
|
||||
\param f The element to insert
|
||||
*/
|
||||
int al_set_func( array_list_t *l, int pos, func_ptr_t f );
|
||||
|
@ -493,24 +493,24 @@ int al_set_func( array_list_t *l, int pos, func_ptr_t f );
|
|||
Returns the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\return The element
|
||||
\param pos The index
|
||||
\return The element
|
||||
*/
|
||||
void *al_get( array_list_t *l, int pos );
|
||||
/**
|
||||
Returns the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\return The element
|
||||
\param pos The index
|
||||
\return The element
|
||||
*/
|
||||
long al_get_long( array_list_t *l, int pos );
|
||||
/**
|
||||
Returns the element at the specified index
|
||||
|
||||
\param l The array_list_t
|
||||
\param pos The index
|
||||
\return The element
|
||||
\param pos The index
|
||||
\return The element
|
||||
*/
|
||||
func_ptr_t al_get_func( array_list_t *l, int pos );
|
||||
|
||||
|
@ -555,12 +555,12 @@ func_ptr_t al_peek_func( array_list_t *l );
|
|||
*/
|
||||
int al_empty( array_list_t *l);
|
||||
|
||||
/**
|
||||
/**
|
||||
Call the function func for each entry in the list
|
||||
*/
|
||||
void al_foreach( array_list_t *l, void (*func)( void * ));
|
||||
|
||||
/**
|
||||
/**
|
||||
Same as al_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
*/
|
||||
|
@ -630,13 +630,13 @@ void sb_append_char( string_buffer_t *, wchar_t );
|
|||
/**
|
||||
Append all specified items to buffer.
|
||||
*/
|
||||
#define sb_append( sb,... ) sb_append_internal( sb, __VA_ARGS__, (void *)0 )
|
||||
#define sb_append( sb,... ) sb_append_internal( sb, __VA_ARGS__, NULL )
|
||||
|
||||
/**
|
||||
Append a null terminated list of strings to the buffer.
|
||||
Example:
|
||||
|
||||
sb_append2( my_buff, L"foo", L"bar", (void *)0 );
|
||||
sb_append2( my_buff, L"foo", L"bar", NULL );
|
||||
|
||||
Do not forget to cast the last 0 to (void *), or you might encounter errors on 64-bit platforms!
|
||||
*/
|
||||
|
@ -655,7 +655,7 @@ int sb_printf( string_buffer_t *buffer, const wchar_t *format, ... );
|
|||
int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig );
|
||||
|
||||
/**
|
||||
Destroy the buffer and free it's memory
|
||||
Destroy the buffer and free its memory
|
||||
*/
|
||||
void sb_destroy( string_buffer_t * );
|
||||
|
||||
|
|
41
wgetopt.cpp
41
wgetopt.cpp
|
@ -1,5 +1,5 @@
|
|||
/** \file wgetopt.c
|
||||
A version of the getopt library for use with wide character strings.
|
||||
A version of the getopt library for use with wide character strings.
|
||||
|
||||
This is simply the gnu getopt library, but converted for use with
|
||||
wchar_t instead of char. This is not usually useful since the argv
|
||||
|
@ -204,9 +204,7 @@ static char *posixly_correct;
|
|||
char *getenv ();
|
||||
|
||||
static wchar_t *
|
||||
my_index (str, chr)
|
||||
const wchar_t *str;
|
||||
int chr;
|
||||
my_index (const wchar_t *str, int chr)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
|
@ -250,14 +248,13 @@ static int last_nonopt;
|
|||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
wchar_t **argv;
|
||||
exchange (wchar_t **argv)
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = woptind;
|
||||
wchar_t *tem;
|
||||
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
|
@ -308,8 +305,7 @@ exchange (argv)
|
|||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const wchar_t *
|
||||
_wgetopt_initialize (optstring)
|
||||
const wchar_t *optstring;
|
||||
_wgetopt_initialize (const wchar_t *optstring)
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
|
@ -398,13 +394,7 @@ _wgetopt_initialize (optstring)
|
|||
long-named options. */
|
||||
|
||||
int
|
||||
_wgetopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
const struct woption *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
_wgetopt_internal (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only)
|
||||
{
|
||||
woptarg = NULL;
|
||||
|
||||
|
@ -696,10 +686,7 @@ int long_only;
|
|||
}
|
||||
|
||||
int
|
||||
wgetopt (argc, argv, optstring)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
wgetopt (int argc, wchar_t *const *argv, const wchar_t *optstring)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, optstring,
|
||||
(const struct woption *) 0,
|
||||
|
@ -708,23 +695,13 @@ wgetopt (argc, argv, optstring)
|
|||
}
|
||||
|
||||
int
|
||||
wgetopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
wgetopt_long (int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
wgetopt_long_only (int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
|
26
wgetopt.h
26
wgetopt.h
|
@ -1,5 +1,5 @@
|
|||
/** \file wgetopt.h
|
||||
A version of the getopt library for use with wide character strings.
|
||||
A version of the getopt library for use with wide character strings.
|
||||
|
||||
This is simply the gnu getopt library, but converted for use with
|
||||
wchar_t instead of char. This is not usually useful since the argv
|
||||
|
@ -115,12 +115,12 @@ struct woption
|
|||
#else
|
||||
wchar_t *name;
|
||||
#endif
|
||||
/**
|
||||
/**
|
||||
Must be one of no_argument, required_argument and
|
||||
optional_argument.
|
||||
|
||||
has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int.
|
||||
type mismatches in all the code that assumes it is an int.
|
||||
*/
|
||||
int has_arg;
|
||||
|
||||
|
@ -153,7 +153,7 @@ struct woption
|
|||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt (int argc, wchar_t *const *argv, const wchar_t *shortopts);
|
||||
|
@ -161,20 +161,20 @@ extern int wgetopt (int argc, wchar_t *const *argv, const wchar_t *shortopts);
|
|||
|
||||
extern int wgetopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt_long (int argc, wchar_t *const *argv, const wchar_t *shortopts,
|
||||
const struct woption *longopts, int *longind);
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt_long_only (int argc, wchar_t *const *argv,
|
||||
const wchar_t *shortopts,
|
||||
const struct woption *longopts, int *longind);
|
||||
|
||||
/**
|
||||
Internal only. Users should not call this directly.
|
||||
/**
|
||||
Internal only. Users should not call this directly.
|
||||
*/
|
||||
extern int _wgetopt_internal (int argc, wchar_t *const *argv,
|
||||
const wchar_t *shortopts,
|
||||
|
@ -182,23 +182,23 @@ extern int _wgetopt_internal (int argc, wchar_t *const *argv,
|
|||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt ();
|
||||
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt_long ();
|
||||
|
||||
/**
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
extern int wgetopt_long_only ();
|
||||
|
||||
/**
|
||||
Internal only. Users should not call this directly.
|
||||
/**
|
||||
Internal only. Users should not call this directly.
|
||||
*/
|
||||
extern int _wgetopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
|
343
wildcard.cpp
343
wildcard.cpp
|
@ -43,7 +43,7 @@ wildcards using **.
|
|||
|
||||
/**
|
||||
The maximum length of a filename token. This is a fallback value,
|
||||
an attempt to find the true value using patchconf is always made.
|
||||
an attempt to find the true value using patchconf is always made.
|
||||
*/
|
||||
#define MAX_FILE_LENGTH 1024
|
||||
|
||||
|
@ -111,20 +111,20 @@ static hash_table_t *suffix_hash=0;
|
|||
which is quite slow if the list is large. It might make sense to
|
||||
use a hashtable for this.
|
||||
*/
|
||||
static void al_push_check( array_list_t *l, const wchar_t *new )
|
||||
static void al_push_check( array_list_t *l, const wchar_t *newv )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < al_get_count(l); i++ )
|
||||
for( i = 0; i < al_get_count(l); i++ )
|
||||
{
|
||||
if( !wcscmp( al_get(l, i), new ) )
|
||||
if( !wcscmp( (const wchar_t *)al_get(l, i), newv ) )
|
||||
{
|
||||
free( (void *)new );
|
||||
free( (void *)newv );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
al_push( l, new );
|
||||
al_push( l, newv );
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ int wildcard_has( const wchar_t *str, int internal )
|
|||
if( !str )
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( internal )
|
||||
|
@ -164,33 +164,33 @@ int wildcard_has( const wchar_t *str, int internal )
|
|||
prev = *str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the string str matches the wildcard string wc.
|
||||
|
||||
|
||||
\param str String to be matched.
|
||||
\param wc The wildcard.
|
||||
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
||||
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
||||
*/
|
||||
static int wildcard_match2( const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
static int wildcard_match2( const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
int is_first )
|
||||
{
|
||||
|
||||
|
||||
if( *str == 0 && *wc==0 )
|
||||
return 1;
|
||||
|
||||
|
||||
if( *wc == ANY_STRING || *wc == ANY_STRING_RECURSIVE)
|
||||
{
|
||||
{
|
||||
/* Ignore hidden file */
|
||||
if( is_first && *str == L'.' )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Try all submatches */
|
||||
do
|
||||
{
|
||||
|
@ -215,10 +215,10 @@ static int wildcard_match2( const wchar_t *str,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return wildcard_match2( str+1, wc+1, 0 );
|
||||
}
|
||||
|
||||
|
||||
if( *wc == *str )
|
||||
return wildcard_match2( str+1, wc+1, 0 );
|
||||
|
||||
|
@ -230,9 +230,9 @@ static int wildcard_match2( const wchar_t *str,
|
|||
possible completion of the string, the remainder of the string is
|
||||
inserted into the array_list_t.
|
||||
*/
|
||||
static int wildcard_complete_internal( const wchar_t *orig,
|
||||
const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
static int wildcard_complete_internal( const wchar_t *orig,
|
||||
const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
int is_first,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *(*desc_func)(const wchar_t *),
|
||||
|
@ -242,7 +242,7 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
if( !wc || !str || !orig)
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( *wc == 0 &&
|
||||
|
@ -250,12 +250,12 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
{
|
||||
wchar_t *out_completion = 0;
|
||||
const wchar_t *out_desc = desc;
|
||||
|
||||
|
||||
if( !out )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( flags & COMPLETE_NO_CASE )
|
||||
{
|
||||
out_completion = wcsdup( orig );
|
||||
|
@ -271,11 +271,11 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
This completion has an embedded description, du not use the generic description
|
||||
*/
|
||||
wchar_t *sep;
|
||||
|
||||
|
||||
sep = wcschr(out_completion, PROG_COMPLETE_SEP );
|
||||
*sep = 0;
|
||||
out_desc = sep + 1;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -290,31 +290,31 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
if( func_desc )
|
||||
out_desc = func_desc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( out_completion )
|
||||
{
|
||||
completion_allocate( out,
|
||||
completion_allocate( out,
|
||||
out_completion,
|
||||
out_desc,
|
||||
flags );
|
||||
}
|
||||
|
||||
|
||||
free ( out_completion );
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if( *wc == ANY_STRING )
|
||||
{
|
||||
{
|
||||
int res=0;
|
||||
|
||||
|
||||
/* Ignore hidden file */
|
||||
if( is_first && str[0] == L'.' )
|
||||
return 0;
|
||||
|
||||
|
||||
/* Try all submatches */
|
||||
do
|
||||
{
|
||||
|
@ -324,12 +324,12 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
}
|
||||
while( *str++ != 0 );
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
else if( *wc == ANY_CHAR )
|
||||
{
|
||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags );
|
||||
}
|
||||
}
|
||||
else if( *wc == *str )
|
||||
{
|
||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags );
|
||||
|
@ -338,19 +338,19 @@ static int wildcard_complete_internal( const wchar_t *orig,
|
|||
{
|
||||
return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE );
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wildcard_complete( const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *(*desc_func)(const wchar_t *),
|
||||
array_list_t *out,
|
||||
int flags )
|
||||
{
|
||||
int res;
|
||||
|
||||
res = wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags );
|
||||
|
||||
res = wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -358,21 +358,21 @@ int wildcard_complete( const wchar_t *str,
|
|||
|
||||
int wildcard_match( const wchar_t *str, const wchar_t *wc )
|
||||
{
|
||||
return wildcard_match2( str, wc, 1 );
|
||||
return wildcard_match2( str, wc, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a path from the specified directory and filename.
|
||||
Creates a path from the specified directory and filename.
|
||||
*/
|
||||
static wchar_t *make_path( const wchar_t *base_dir, const wchar_t *name )
|
||||
{
|
||||
|
||||
|
||||
wchar_t *long_name;
|
||||
int base_len = wcslen( base_dir );
|
||||
if( !(long_name= malloc( sizeof(wchar_t)*(base_len+wcslen(name)+1) )))
|
||||
if( !(long_name= (wchar_t *)malloc( sizeof(wchar_t)*(base_len+wcslen(name)+1) )))
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
}
|
||||
wcscpy( long_name, base_dir );
|
||||
wcscpy(&long_name[base_len], name );
|
||||
return long_name;
|
||||
|
@ -393,12 +393,12 @@ static wchar_t *complete_get_desc_suffix_internal( const wchar_t *suff_orig )
|
|||
|
||||
if( !suff || !cmd )
|
||||
DIE_MEM();
|
||||
|
||||
|
||||
al_init( &l );
|
||||
|
||||
|
||||
if( exec_subshell( cmd, &l ) != -1 )
|
||||
{
|
||||
|
||||
|
||||
if( al_get_count( &l )>0 )
|
||||
{
|
||||
wchar_t *ln = (wchar_t *)al_get(&l, 0 );
|
||||
|
@ -414,16 +414,16 @@ static wchar_t *complete_get_desc_suffix_internal( const wchar_t *suff_orig )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(cmd);
|
||||
al_foreach( &l, &free );
|
||||
al_destroy( &l );
|
||||
|
||||
|
||||
if( !desc )
|
||||
{
|
||||
desc = wcsdup(COMPLETE_FILE_DESC);
|
||||
}
|
||||
|
||||
|
||||
hash_put( suffix_hash, suff, desc );
|
||||
|
||||
return desc;
|
||||
|
@ -458,13 +458,13 @@ static const wchar_t *complete_get_desc_suffix( const wchar_t *suff_orig )
|
|||
wchar_t *desc;
|
||||
|
||||
len = wcslen(suff_orig );
|
||||
|
||||
|
||||
if( len == 0 )
|
||||
return COMPLETE_FILE_DESC;
|
||||
|
||||
if( !suffix_hash )
|
||||
{
|
||||
suffix_hash = malloc( sizeof( hash_table_t) );
|
||||
suffix_hash = (hash_table_t *)malloc( sizeof( hash_table_t) );
|
||||
if( !suffix_hash )
|
||||
DIE_MEM();
|
||||
hash_init( suffix_hash, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
@ -494,7 +494,7 @@ static const wchar_t *complete_get_desc_suffix( const wchar_t *suff_orig )
|
|||
{
|
||||
desc = complete_get_desc_suffix_internal( suff );
|
||||
}
|
||||
|
||||
|
||||
free( suff );
|
||||
|
||||
return desc;
|
||||
|
@ -511,20 +511,20 @@ static const wchar_t *complete_get_desc_suffix( const wchar_t *suff_orig )
|
|||
\param lbuf The struct buf output of calling lstat on the file
|
||||
\param stat_res The result of calling stat on the file
|
||||
\param buf The struct buf output of calling stat on the file
|
||||
\param err The errno value after a failed stat call on the file.
|
||||
\param err The errno value after a failed stat call on the file.
|
||||
*/
|
||||
|
||||
static const wchar_t *file_get_desc( const wchar_t *filename,
|
||||
static const wchar_t *file_get_desc( const wchar_t *filename,
|
||||
int lstat_res,
|
||||
struct stat lbuf,
|
||||
int stat_res,
|
||||
struct stat buf,
|
||||
struct stat lbuf,
|
||||
int stat_res,
|
||||
struct stat buf,
|
||||
int err )
|
||||
{
|
||||
wchar_t *suffix;
|
||||
|
||||
CHECK( filename, 0 );
|
||||
|
||||
|
||||
if( !lstat_res )
|
||||
{
|
||||
if( S_ISLNK(lbuf.st_mode))
|
||||
|
@ -542,7 +542,7 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
( buf.st_mode & S_IXGRP ) ||
|
||||
( buf.st_mode & S_IXOTH ) )
|
||||
{
|
||||
|
||||
|
||||
if( waccess( filename, X_OK ) == 0 )
|
||||
{
|
||||
/*
|
||||
|
@ -557,7 +557,7 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return COMPLETE_SYMLINK_DESC;
|
||||
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
{
|
||||
return COMPLETE_ROTTEN_SYMLINK_DESC;
|
||||
}
|
||||
|
||||
|
||||
case ELOOP:
|
||||
{
|
||||
return COMPLETE_LOOP_SYMLINK_DESC;
|
||||
|
@ -602,13 +602,13 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
{
|
||||
return COMPLETE_DIRECTORY_DESC;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if( ( buf.st_mode & S_IXUSR ) ||
|
||||
( buf.st_mode & S_IXGRP ) ||
|
||||
( buf.st_mode & S_IXOTH ) )
|
||||
{
|
||||
|
||||
|
||||
if( waccess( filename, X_OK ) == 0 )
|
||||
{
|
||||
/*
|
||||
|
@ -624,19 +624,19 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suffix = wcsrchr( filename, L'.' );
|
||||
if( suffix != 0 && !wcsrchr( suffix, L'/' ) )
|
||||
{
|
||||
return complete_get_desc_suffix( suffix );
|
||||
}
|
||||
|
||||
|
||||
return COMPLETE_FILE_DESC ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Add the specified filename if it matches the specified wildcard.
|
||||
Add the specified filename if it matches the specified wildcard.
|
||||
|
||||
If the filename matches, first get the description of the specified
|
||||
filename. If this is a regular file, append the filesize to the
|
||||
|
@ -648,8 +648,8 @@ static const wchar_t *file_get_desc( const wchar_t *filename,
|
|||
\param wc the wildcard to match against
|
||||
\param is_cmd whether we are performing command completion
|
||||
*/
|
||||
static void wildcard_completion_allocate( array_list_t *list,
|
||||
const wchar_t *fullname,
|
||||
static void wildcard_completion_allocate( array_list_t *list,
|
||||
const wchar_t *fullname,
|
||||
const wchar_t *completion,
|
||||
const wchar_t *wc,
|
||||
int is_cmd )
|
||||
|
@ -657,14 +657,14 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
const wchar_t *desc;
|
||||
struct stat buf, lbuf;
|
||||
static string_buffer_t *sb = 0;
|
||||
|
||||
|
||||
int free_completion = 0;
|
||||
|
||||
|
||||
int flags = 0;
|
||||
int stat_res, lstat_res;
|
||||
int stat_errno=0;
|
||||
|
||||
long long sz;
|
||||
|
||||
long long sz;
|
||||
|
||||
if( !sb )
|
||||
{
|
||||
|
@ -676,7 +676,7 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
}
|
||||
|
||||
CHECK( fullname, );
|
||||
|
||||
|
||||
sb_clear( sb );
|
||||
|
||||
/*
|
||||
|
@ -694,7 +694,7 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
{
|
||||
if( S_ISLNK(lbuf.st_mode))
|
||||
{
|
||||
|
||||
|
||||
if( ( stat_res = wstat( fullname, &buf ) ) )
|
||||
{
|
||||
sz=-1;
|
||||
|
@ -703,7 +703,7 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
{
|
||||
sz = (long long)buf.st_size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
In order to differentiate between e.g. rotten symlinks
|
||||
and symlink loops, we also need to know the error status of wstat.
|
||||
|
@ -717,9 +717,9 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
sz = (long long)buf.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
desc = file_get_desc( fullname, lstat_res, lbuf, stat_res, buf, stat_errno );
|
||||
|
||||
|
||||
if( sz >= 0 && S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
free_completion = 1;
|
||||
|
@ -728,8 +728,8 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
sb_append( sb, desc );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_append( sb, desc, L", ", (void *)0 );
|
||||
{
|
||||
sb_append( sb, desc, L", ", NULL );
|
||||
sb_format_size( sb, sz );
|
||||
}
|
||||
|
||||
|
@ -743,7 +743,7 @@ static void wildcard_completion_allocate( array_list_t *list,
|
|||
expansion flags specified. flags can be a combination of
|
||||
EXECUTABLES_ONLY and DIRECTORIES_ONLY.
|
||||
*/
|
||||
static int test_flags( wchar_t *filename,
|
||||
static int test_flags( const wchar_t *filename,
|
||||
int flags )
|
||||
{
|
||||
if( flags & DIRECTORIES_ONLY )
|
||||
|
@ -759,14 +759,14 @@ static int test_flags( wchar_t *filename,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if( flags & EXECUTABLES_ONLY )
|
||||
{
|
||||
if ( waccess( filename, X_OK ) != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -776,24 +776,23 @@ static int test_flags( wchar_t *filename,
|
|||
|
||||
This function traverses the relevant directory tree looking for
|
||||
matches, and recurses when needed to handle wildcrards spanning
|
||||
multiple components and recursive wildcards.
|
||||
multiple components and recursive wildcards.
|
||||
*/
|
||||
static int wildcard_expand_internal( const wchar_t *wc,
|
||||
static int wildcard_expand_internal( const wchar_t *wc,
|
||||
const wchar_t *base_dir,
|
||||
int flags,
|
||||
array_list_t *out )
|
||||
{
|
||||
|
||||
|
||||
/* Points to the end of the current wildcard segment */
|
||||
wchar_t *wc_end;
|
||||
|
||||
/* Variables for traversing a directory */
|
||||
struct wdirent *next;
|
||||
DIR *dir;
|
||||
|
||||
|
||||
/* The result returned */
|
||||
int res = 0;
|
||||
|
||||
|
||||
/* Length of the directory to search in */
|
||||
int base_len;
|
||||
|
||||
|
@ -806,24 +805,24 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
|
||||
/* Description for completions */
|
||||
string_buffer_t sb_desc;
|
||||
|
||||
|
||||
// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );
|
||||
|
||||
if( reader_interrupted() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if( !wc || !base_dir || !out)
|
||||
{
|
||||
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
/*
|
||||
Avoid excessive number of returned matches for wc ending with a *
|
||||
{
|
||||
/*
|
||||
Avoid excessive number of returned matches for wc ending with a *
|
||||
*/
|
||||
int len = wcslen(wc);
|
||||
if( len && (wc[len-1]==ANY_STRING) )
|
||||
|
@ -832,7 +831,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
foo[len-1]=0;
|
||||
int res = wildcard_expand_internal( foo, base_dir, flags, out );
|
||||
free( foo );
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,7 +840,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
*/
|
||||
|
||||
dir_string = base_dir[0]==L'\0'?L".":base_dir;
|
||||
|
||||
|
||||
if( !(dir = wopendir( dir_string )))
|
||||
{
|
||||
return 0;
|
||||
|
@ -852,7 +851,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
|
||||
/*
|
||||
Test for recursive match string in current segment
|
||||
*/
|
||||
*/
|
||||
wc_recursive = wcschr( wc, ANY_STRING_RECURSIVE );
|
||||
is_recursive = ( wc_recursive && (!wc_end || wc_recursive < wc_end));
|
||||
|
||||
|
@ -877,13 +876,14 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
*/
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
wcstring next;
|
||||
while(wreaddir(dir, next))
|
||||
{
|
||||
if( next->d_name[0] != L'.' )
|
||||
if( next[0] != L'.' )
|
||||
{
|
||||
wchar_t *name = next->d_name;
|
||||
wchar_t *long_name = make_path( base_dir, name );
|
||||
|
||||
const wchar_t *name = next.c_str();
|
||||
const wchar_t *long_name = make_path( base_dir, name );
|
||||
|
||||
if( test_flags( long_name, flags ) )
|
||||
{
|
||||
wildcard_completion_allocate( out,
|
||||
|
@ -892,33 +892,34 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
L"",
|
||||
flags & EXECUTABLES_ONLY );
|
||||
}
|
||||
|
||||
free( long_name );
|
||||
}
|
||||
|
||||
free( (void *)long_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
res = 1;
|
||||
al_push_check( out, wcsdup( base_dir ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
This is the last wildcard segment, and it is not empty. Match files/directories.
|
||||
*/
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
wcstring next;
|
||||
while(wreaddir(dir, next))
|
||||
{
|
||||
wchar_t *name = next->d_name;
|
||||
|
||||
const wchar_t *name = next.c_str();
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
|
||||
|
||||
wchar_t *long_name = make_path( base_dir, name );
|
||||
|
||||
/*
|
||||
Test for matches before stating file, so as to minimize the number of calls to the much slower stat function
|
||||
Test for matches before stating file, so as to minimize the number of calls to the much slower stat function
|
||||
*/
|
||||
if( wildcard_complete( name,
|
||||
wc,
|
||||
|
@ -934,12 +935,12 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
name,
|
||||
wc,
|
||||
flags & EXECUTABLES_ONLY );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( long_name );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -947,7 +948,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
{
|
||||
wchar_t *long_name = make_path( base_dir, name );
|
||||
int skip = 0;
|
||||
|
||||
|
||||
if( is_recursive )
|
||||
{
|
||||
/*
|
||||
|
@ -959,9 +960,9 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
if( !wstat( long_name, &buf ) )
|
||||
{
|
||||
skip = S_ISDIR(buf.st_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( skip )
|
||||
{
|
||||
free( long_name );
|
||||
|
@ -983,7 +984,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
Wilcard segment is not the last segment. Recursively call
|
||||
wildcard_expand for all matching subdirectories.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
wc_str is the part of the wildcarded string from the
|
||||
beginning to the first slash
|
||||
|
@ -1010,20 +1011,20 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
|
||||
if( narrow_dir_string )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
Find out how long the filename can be in a worst case
|
||||
scenario
|
||||
*/
|
||||
ln = pathconf( narrow_dir_string, _PC_NAME_MAX );
|
||||
ln = pathconf( narrow_dir_string, _PC_NAME_MAX );
|
||||
|
||||
/*
|
||||
If not specified, use som large number as fallback
|
||||
*/
|
||||
if( ln < 0 )
|
||||
ln = MAX_FILE_LENGTH;
|
||||
ln = MAX_FILE_LENGTH;
|
||||
free( narrow_dir_string );
|
||||
}
|
||||
new_dir= malloc( sizeof(wchar_t)*(base_len+ln+2) );
|
||||
new_dir= (wchar_t *)malloc( sizeof(wchar_t)*(base_len+ln+2) );
|
||||
|
||||
wc_str = wc_end?wcsndup(wc, wc_end-wc):wcsdup(wc);
|
||||
|
||||
|
@ -1033,19 +1034,20 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
}
|
||||
|
||||
wcscpy( new_dir, base_dir );
|
||||
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
|
||||
wcstring next;
|
||||
while (wreaddir(dir, next))
|
||||
{
|
||||
wchar_t *name = next->d_name;
|
||||
|
||||
const wchar_t *name = next.c_str();
|
||||
|
||||
/*
|
||||
Test if the file/directory name matches the whole
|
||||
wildcard element, i.e. regular matching.
|
||||
*/
|
||||
int whole_match = wildcard_match2( name, wc_str, 1 );
|
||||
int partial_match = 0;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
If we are doing recursive matching, also check if this
|
||||
directory matches the part up to the recusrive
|
||||
wildcard, if so, then we can search all subdirectories
|
||||
|
@ -1057,24 +1059,24 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
wchar_t *wc_sub = wcsndup( wc, end-wc+1);
|
||||
partial_match = wildcard_match2( name, wc_sub, 1 );
|
||||
free( wc_sub );
|
||||
}
|
||||
}
|
||||
|
||||
if( whole_match || partial_match )
|
||||
{
|
||||
int new_len;
|
||||
struct stat buf;
|
||||
struct stat buf;
|
||||
char *dir_str;
|
||||
int stat_res;
|
||||
int new_res;
|
||||
|
||||
wcscpy(&new_dir[base_len], name );
|
||||
dir_str = wcs2str( new_dir );
|
||||
|
||||
|
||||
if( dir_str )
|
||||
{
|
||||
stat_res = stat( dir_str, &buf );
|
||||
free( dir_str );
|
||||
|
||||
|
||||
if( !stat_res )
|
||||
{
|
||||
if( S_ISDIR(buf.st_mode) )
|
||||
|
@ -1082,7 +1084,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
new_len = wcslen( new_dir );
|
||||
new_dir[new_len] = L'/';
|
||||
new_dir[new_len+1] = L'\0';
|
||||
|
||||
|
||||
/*
|
||||
Regular matching
|
||||
*/
|
||||
|
@ -1100,51 +1102,51 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
new_wc++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new_res = wildcard_expand_internal( new_wc,
|
||||
new_dir,
|
||||
flags,
|
||||
new_dir,
|
||||
flags,
|
||||
out );
|
||||
|
||||
if( new_res == -1 )
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
res |= new_res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Recursive matching
|
||||
*/
|
||||
if( partial_match )
|
||||
{
|
||||
|
||||
new_res = wildcard_expand_internal( wcschr( wc, ANY_STRING_RECURSIVE ),
|
||||
|
||||
new_res = wildcard_expand_internal( wcschr( wc, ANY_STRING_RECURSIVE ),
|
||||
new_dir,
|
||||
flags | WILDCARD_RECURSIVE,
|
||||
flags | WILDCARD_RECURSIVE,
|
||||
out );
|
||||
|
||||
if( new_res == -1 )
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
res |= new_res;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( wc_str );
|
||||
free( new_dir );
|
||||
}
|
||||
closedir( dir );
|
||||
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
sb_destroy( &sb_desc );
|
||||
|
@ -1154,7 +1156,7 @@ static int wildcard_expand_internal( const wchar_t *wc,
|
|||
}
|
||||
|
||||
|
||||
int wildcard_expand( const wchar_t *wc,
|
||||
int wildcard_expand( const wchar_t *wc,
|
||||
const wchar_t *base_dir,
|
||||
int flags,
|
||||
array_list_t *out )
|
||||
|
@ -1162,41 +1164,58 @@ int wildcard_expand( const wchar_t *wc,
|
|||
int c = al_get_count( out );
|
||||
int res = wildcard_expand_internal( wc, base_dir, flags, out );
|
||||
int i;
|
||||
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *wc_base=L"";
|
||||
wchar_t *wc_base_ptr = wcsrchr( wc, L'/' );
|
||||
string_buffer_t sb;
|
||||
|
||||
|
||||
|
||||
if( wc_base_ptr )
|
||||
{
|
||||
wc_base = wcsndup( wc, (wc_base_ptr-wc)+1 );
|
||||
}
|
||||
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=c; i<al_get_count( out ); i++ )
|
||||
{
|
||||
completion_t *c = al_get( out, i );
|
||||
|
||||
completion_t *c = (completion_t *)al_get( out, i );
|
||||
|
||||
if( c->flags & COMPLETE_NO_CASE )
|
||||
{
|
||||
sb_clear( &sb );
|
||||
sb_printf( &sb, L"%ls%ls%ls", base_dir, wc_base, c->completion );
|
||||
|
||||
|
||||
c->completion = halloc_wcsdup( out, (wchar_t *)sb.buff );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sb_destroy( &sb );
|
||||
|
||||
if( wc_base_ptr )
|
||||
{
|
||||
free( wc_base );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, int flags, std::vector<wcstring> &outputs )
|
||||
{
|
||||
array_list_t lst;
|
||||
al_init(&lst);
|
||||
|
||||
int res = wildcard_expand(wc.c_str(), base_dir.c_str(), flags, &lst);
|
||||
|
||||
int i, max = al_get_count(&lst);
|
||||
for (i=0; i < max; i++) {
|
||||
wchar_t *tmp = (wchar_t *)al_get(&lst, i);
|
||||
outputs.push_back(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
al_destroy(&lst);
|
||||
return res;
|
||||
}
|
||||
|
|
20
wildcard.h
20
wildcard.h
|
@ -1,4 +1,4 @@
|
|||
/** \file wildcard.h
|
||||
/** \file wildcard.h
|
||||
|
||||
My own globbing implementation. Needed to implement this instead
|
||||
of using libs globbing to support tab-expansion of globbed
|
||||
|
@ -13,8 +13,10 @@
|
|||
#define FISH_WILDCARD_H
|
||||
|
||||
#include <wchar.h>
|
||||
#include <vector>
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
Use unencoded private-use keycodes for internal characters
|
||||
|
@ -39,7 +41,7 @@ enum
|
|||
;
|
||||
|
||||
/**
|
||||
Expand the wildcard by matching against the filesystem.
|
||||
Expand the wildcard by matching against the filesystem.
|
||||
|
||||
New strings are allocated using malloc and should be freed by the caller.
|
||||
|
||||
|
@ -61,12 +63,14 @@ enum
|
|||
\param out The list in which to put the output
|
||||
|
||||
\return 1 if matches where found, 0 otherwise. Return -1 on abort (I.e. ^C was pressed).
|
||||
|
||||
|
||||
*/
|
||||
int wildcard_expand( const wchar_t *wc,
|
||||
const wchar_t *base_dir,
|
||||
int flags,
|
||||
int wildcard_expand( const wchar_t *wc,
|
||||
const wchar_t *base_dir,
|
||||
int flags,
|
||||
array_list_t *out );
|
||||
|
||||
int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, int flags, std::vector<wcstring> &out );
|
||||
/**
|
||||
Test whether the given wildcard matches the string
|
||||
|
||||
|
@ -74,7 +78,7 @@ int wildcard_expand( const wchar_t *wc,
|
|||
\param wc The wildcard to test against
|
||||
\return true if the wildcard matched
|
||||
*/
|
||||
int wildcard_match( const wchar_t *str,
|
||||
int wildcard_match( const wchar_t *str,
|
||||
const wchar_t *wc );
|
||||
|
||||
|
||||
|
@ -88,7 +92,7 @@ int wildcard_has( const wchar_t *str, int internal );
|
|||
*/
|
||||
int wildcard_complete( const wchar_t *str,
|
||||
const wchar_t *wc,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *(*desc_func)(const wchar_t *),
|
||||
array_list_t *out,
|
||||
int flags );
|
||||
|
|
350
wutil.cpp
350
wutil.cpp
|
@ -18,6 +18,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
#include <string>
|
||||
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
|
@ -31,6 +32,8 @@
|
|||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
typedef std::string cstring;
|
||||
|
||||
/**
|
||||
Minimum length of the internal covnersion buffers
|
||||
*/
|
||||
|
@ -47,40 +50,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
Buffer for converting wide arguments to narrow arguments, used by
|
||||
the \c wutil_wcs2str() function.
|
||||
*/
|
||||
static char *tmp=0;
|
||||
|
||||
/**
|
||||
Buffer for converting narrow results to wide ones, used by the \c
|
||||
wutil_str2wcs() function. Avoid usign this without thinking about
|
||||
it, since subsequent calls will overwrite previous values.
|
||||
*/
|
||||
static wchar_t *tmp2;
|
||||
|
||||
/**
|
||||
Length of the \c tmp buffer.
|
||||
*/
|
||||
static size_t tmp_len=0;
|
||||
|
||||
/**
|
||||
Length of the \c tmp2 buffer
|
||||
*/
|
||||
static size_t tmp2_len;
|
||||
|
||||
/**
|
||||
Counts the number of calls to the wutil wrapper functions
|
||||
*/
|
||||
static int wutil_calls = 0;
|
||||
|
||||
/**
|
||||
Storage for the wreaddir function
|
||||
*/
|
||||
static struct wdirent my_wdirent;
|
||||
|
||||
|
||||
/**
|
||||
For wgettext: Number of string_buffer_t in the ring of buffers
|
||||
*/
|
||||
|
@ -118,223 +87,110 @@ void wutil_init()
|
|||
|
||||
void wutil_destroy()
|
||||
{
|
||||
free( tmp );
|
||||
free( tmp2 );
|
||||
|
||||
tmp=0;
|
||||
tmp_len=0;
|
||||
debug( 3, L"wutil functions called %d times", wutil_calls );
|
||||
}
|
||||
|
||||
/**
|
||||
Convert the specified wide aharacter string to a narrow character
|
||||
string. This function uses an internal temporary buffer for storing
|
||||
the result so subsequent results will overwrite previous results.
|
||||
*/
|
||||
static char *wutil_wcs2str( const wchar_t *in )
|
||||
std::wstring *wreaddir(DIR *dir, std::wstring &outPath)
|
||||
{
|
||||
size_t new_sz;
|
||||
|
||||
wutil_calls++;
|
||||
|
||||
new_sz =MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
if( tmp_len < new_sz )
|
||||
{
|
||||
new_sz = maxi( new_sz, TMP_LEN_MIN );
|
||||
tmp = realloc( tmp, new_sz );
|
||||
if( !tmp )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
tmp_len = new_sz;
|
||||
}
|
||||
|
||||
return wcs2str_internal( in, tmp );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert the specified wide character string to a narrow character
|
||||
string. This function uses an internal temporary buffer for storing
|
||||
the result so subsequent results will overwrite previous results.
|
||||
*/
|
||||
static wchar_t *wutil_str2wcs( const char *in )
|
||||
{
|
||||
size_t new_sz;
|
||||
|
||||
wutil_calls++;
|
||||
|
||||
new_sz = sizeof(wchar_t)*(strlen(in)+1);
|
||||
if( tmp2_len < new_sz )
|
||||
{
|
||||
new_sz = maxi( new_sz, TMP_LEN_MIN );
|
||||
tmp2 = realloc( tmp2, new_sz );
|
||||
if( !tmp2 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
tmp2_len = new_sz;
|
||||
}
|
||||
|
||||
return str2wcs_internal( in, tmp2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct wdirent *wreaddir(DIR *dir )
|
||||
{
|
||||
struct dirent *d = readdir( dir );
|
||||
if( !d )
|
||||
return 0;
|
||||
|
||||
my_wdirent.d_name = wutil_str2wcs( d->d_name );
|
||||
return &my_wdirent;
|
||||
|
||||
struct dirent *d = readdir( dir );
|
||||
if ( !d ) return 0;
|
||||
|
||||
outPath = str2wcstring(d->d_name);
|
||||
return &outPath;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *wgetcwd( wchar_t *buff, size_t sz )
|
||||
{
|
||||
char *buffc = malloc( sz*MAX_UTF8_BYTES);
|
||||
char *buffc = (char *)malloc( sz*MAX_UTF8_BYTES);
|
||||
char *res;
|
||||
wchar_t *ret = 0;
|
||||
|
||||
|
||||
if( !buffc )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
res = getcwd( buffc, sz*MAX_UTF8_BYTES );
|
||||
if( res )
|
||||
{
|
||||
if( (size_t)-1 != mbstowcs( buff, buffc, sizeof( wchar_t ) * sz ) )
|
||||
{
|
||||
ret = buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( buffc );
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wchdir( const wchar_t * dir )
|
||||
{
|
||||
char *tmp = wutil_wcs2str(dir);
|
||||
return chdir( tmp );
|
||||
cstring tmp = wcs2string(dir);
|
||||
return chdir( tmp.c_str() );
|
||||
}
|
||||
|
||||
FILE *wfopen(const wchar_t *path, const char *mode)
|
||||
{
|
||||
|
||||
char *tmp =wutil_wcs2str(path);
|
||||
FILE *res=0;
|
||||
if( tmp )
|
||||
{
|
||||
res = fopen(tmp, mode);
|
||||
|
||||
}
|
||||
return res;
|
||||
cstring tmp = wcs2string(path);
|
||||
return fopen(tmp.c_str(), mode);
|
||||
}
|
||||
|
||||
FILE *wfreopen(const wchar_t *path, const char *mode, FILE *stream)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(path);
|
||||
FILE *res=0;
|
||||
if( tmp )
|
||||
{
|
||||
res = freopen(tmp, mode, stream);
|
||||
}
|
||||
return res;
|
||||
cstring tmp = wcs2string(path);
|
||||
return freopen(tmp.c_str(), mode, stream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int wopen(const wchar_t *pathname, int flags, ...)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(pathname);
|
||||
cstring tmp = wcs2string(pathname);
|
||||
int res=-1;
|
||||
va_list argp;
|
||||
|
||||
if( tmp )
|
||||
{
|
||||
|
||||
if( ! (flags & O_CREAT) )
|
||||
{
|
||||
res = open(tmp, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
va_start( argp, flags );
|
||||
res = open(tmp, flags, va_arg(argp, int) );
|
||||
va_end( argp );
|
||||
}
|
||||
}
|
||||
|
||||
va_list argp;
|
||||
if( ! (flags & O_CREAT) )
|
||||
{
|
||||
res = open(tmp.c_str(), flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
va_start( argp, flags );
|
||||
res = open(tmp.c_str(), flags, va_arg(argp, int) );
|
||||
va_end( argp );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int wcreat(const wchar_t *pathname, mode_t mode)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(pathname);
|
||||
int res = -1;
|
||||
if( tmp )
|
||||
{
|
||||
res= creat(tmp, mode);
|
||||
}
|
||||
|
||||
return res;
|
||||
cstring tmp = wcs2string(pathname);
|
||||
return creat(tmp.c_str(), mode);
|
||||
}
|
||||
|
||||
DIR *wopendir(const wchar_t *name)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(name);
|
||||
DIR *res = 0;
|
||||
if( tmp )
|
||||
{
|
||||
res = opendir(tmp);
|
||||
}
|
||||
|
||||
return res;
|
||||
cstring tmp = wcs2string(name);
|
||||
return opendir(tmp.c_str());
|
||||
}
|
||||
|
||||
int wstat(const wchar_t *file_name, struct stat *buf)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(file_name);
|
||||
int res = -1;
|
||||
|
||||
if( tmp )
|
||||
{
|
||||
res = stat(tmp, buf);
|
||||
}
|
||||
|
||||
return res;
|
||||
cstring tmp = wcs2string(file_name);
|
||||
return stat(tmp.c_str(), buf);
|
||||
}
|
||||
|
||||
int lwstat(const wchar_t *file_name, struct stat *buf)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(file_name);
|
||||
int res = -1;
|
||||
|
||||
if( tmp )
|
||||
{
|
||||
res = lstat(tmp, buf);
|
||||
}
|
||||
|
||||
return res;
|
||||
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
||||
cstring tmp = wcs2string(file_name);
|
||||
return lstat(tmp.c_str(), buf);
|
||||
}
|
||||
|
||||
|
||||
int waccess(const wchar_t *file_name, int mode)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(file_name);
|
||||
int res = -1;
|
||||
if( tmp )
|
||||
{
|
||||
res= access(tmp, mode);
|
||||
}
|
||||
return res;
|
||||
cstring tmp = wcs2string(file_name);
|
||||
return access(tmp.c_str(), mode);
|
||||
}
|
||||
|
||||
void wperror(const wchar_t *s)
|
||||
|
@ -351,19 +207,19 @@ void wperror(const wchar_t *s)
|
|||
|
||||
wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
||||
{
|
||||
char *tmp = wutil_wcs2str(pathname);
|
||||
char *narrow_res = realpath( tmp, 0 );
|
||||
wchar_t *res;
|
||||
cstring tmp = wcs2string(pathname);
|
||||
char *narrow_res = realpath( tmp.c_str(), 0 );
|
||||
wchar_t *res;
|
||||
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
|
||||
if( resolved_path )
|
||||
{
|
||||
wchar_t *tmp2 = str2wcs( narrow_res );
|
||||
wcslcpy( resolved_path, tmp2, PATH_MAX );
|
||||
free( tmp2 );
|
||||
res = resolved_path;
|
||||
res = resolved_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -379,20 +235,20 @@ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
|||
|
||||
wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
||||
{
|
||||
char *tmp = wutil_wcs2str(pathname);
|
||||
cstring tmp = wcs2string(pathname);
|
||||
char narrow_buff[PATH_MAX];
|
||||
char *narrow_res = realpath( tmp, narrow_buff );
|
||||
wchar_t *res;
|
||||
char *narrow_res = realpath( tmp.c_str(), narrow_buff );
|
||||
wchar_t *res;
|
||||
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
|
||||
if( resolved_path )
|
||||
{
|
||||
wchar_t *tmp2 = str2wcs( narrow_res );
|
||||
wcslcpy( resolved_path, tmp2, PATH_MAX );
|
||||
free( tmp2 );
|
||||
res = resolved_path;
|
||||
res = resolved_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -404,43 +260,24 @@ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
|||
#endif
|
||||
|
||||
|
||||
wchar_t *wdirname( wchar_t *path )
|
||||
wcstring wdirname( const wcstring &path )
|
||||
{
|
||||
static string_buffer_t *sb = 0;
|
||||
if( sb )
|
||||
sb_clear(sb);
|
||||
else
|
||||
sb = sb_halloc( global_context );
|
||||
|
||||
char *tmp =wutil_wcs2str(path);
|
||||
char *narrow_res = dirname( tmp );
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
sb_printf( sb, L"%s", narrow_res );
|
||||
wcscpy( path, (wchar_t *)sb->buff );
|
||||
return path;
|
||||
char *tmp = wcs2str(path.c_str());
|
||||
char *narrow_res = dirname( tmp );
|
||||
wcstring result = format_string(L"%s", narrow_res);
|
||||
free(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
wchar_t *wbasename( const wchar_t *path )
|
||||
wcstring wbasename( const wcstring &path )
|
||||
{
|
||||
static string_buffer_t *sb = 0;
|
||||
if( sb )
|
||||
sb_clear(sb);
|
||||
else
|
||||
sb = sb_halloc( global_context );
|
||||
|
||||
char *tmp =wutil_wcs2str(path);
|
||||
char *narrow_res = basename( tmp );
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
sb_printf( sb, L"%s", narrow_res );
|
||||
return (wchar_t *)sb->buff;
|
||||
char *tmp = wcs2str(path.c_str());
|
||||
char *narrow_res = basename( tmp );
|
||||
wcstring result = format_string(L"%s", narrow_res);
|
||||
free(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
For wgettext: Internal shutdown function. Automatically called on shutdown if the library has been initialized.
|
||||
*/
|
||||
|
@ -450,9 +287,9 @@ static void wgettext_destroy()
|
|||
|
||||
if( !wgettext_is_init )
|
||||
return;
|
||||
|
||||
|
||||
wgettext_is_init = 0;
|
||||
|
||||
|
||||
for(i=0; i<BUFF_COUNT; i++ )
|
||||
sb_destroy( &buff[i] );
|
||||
|
||||
|
@ -465,16 +302,16 @@ static void wgettext_destroy()
|
|||
static void wgettext_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
wgettext_is_init = 1;
|
||||
|
||||
|
||||
for( i=0; i<BUFF_COUNT; i++ )
|
||||
{
|
||||
sb_init( &buff[i] );
|
||||
}
|
||||
|
||||
|
||||
halloc_register_function_void( global_context, &wgettext_destroy );
|
||||
|
||||
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
textdomain( PACKAGE_NAME );
|
||||
}
|
||||
|
@ -489,13 +326,13 @@ static char *wgettext_wcs2str( const wchar_t *in )
|
|||
size_t len = MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
if( len > wcs2str_buff_count )
|
||||
{
|
||||
wcs2str_buff = realloc( wcs2str_buff, len );
|
||||
wcs2str_buff = (char *)realloc( wcs2str_buff, len );
|
||||
if( !wcs2str_buff )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return wcs2str_internal( in, wcs2str_buff);
|
||||
}
|
||||
|
||||
|
@ -503,32 +340,32 @@ const wchar_t *wgettext( const wchar_t *in )
|
|||
{
|
||||
if( !in )
|
||||
return in;
|
||||
|
||||
|
||||
if( !wgettext_is_init )
|
||||
wgettext_init();
|
||||
|
||||
char *mbs_in = wgettext_wcs2str( in );
|
||||
|
||||
char *mbs_in = wgettext_wcs2str( in );
|
||||
char *out = gettext( mbs_in );
|
||||
wchar_t *wres=0;
|
||||
|
||||
|
||||
sb_clear( &buff[curr_buff] );
|
||||
|
||||
|
||||
sb_printf( &buff[curr_buff], L"%s", out );
|
||||
wres = (wchar_t *)buff[curr_buff].buff;
|
||||
curr_buff = (curr_buff+1)%BUFF_COUNT;
|
||||
|
||||
|
||||
return wres;
|
||||
}
|
||||
|
||||
wchar_t *wgetenv( const wchar_t *name )
|
||||
{
|
||||
char *name_narrow =wutil_wcs2str(name);
|
||||
char *res_narrow = getenv( name_narrow );
|
||||
cstring name_narrow = wcs2string(name);
|
||||
char *res_narrow = getenv( name_narrow.c_str() );
|
||||
static string_buffer_t *out = 0;
|
||||
|
||||
if( !res_narrow )
|
||||
return 0;
|
||||
|
||||
|
||||
if( !out )
|
||||
{
|
||||
out = sb_halloc( global_context );
|
||||
|
@ -539,25 +376,20 @@ wchar_t *wgetenv( const wchar_t *name )
|
|||
}
|
||||
|
||||
sb_printf( out, L"%s", res_narrow );
|
||||
|
||||
|
||||
return (wchar_t *)out->buff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int wmkdir( const wchar_t *name, int mode )
|
||||
{
|
||||
char *name_narrow =wutil_wcs2str(name);
|
||||
return mkdir( name_narrow, mode );
|
||||
cstring name_narrow = wcs2string(name);
|
||||
return mkdir( name_narrow.c_str(), mode );
|
||||
}
|
||||
|
||||
int wrename( const wchar_t *old, const wchar_t *new )
|
||||
int wrename( const wchar_t *old, const wchar_t *newv )
|
||||
{
|
||||
char *old_narrow =wutil_wcs2str(old);
|
||||
char *new_narrow =wcs2str(new);
|
||||
int res;
|
||||
|
||||
res = rename( old_narrow, new_narrow );
|
||||
free( new_narrow );
|
||||
|
||||
return res;
|
||||
cstring old_narrow = wcs2string(old);
|
||||
cstring new_narrow =wcs2string(newv);
|
||||
return rename( old_narrow.c_str(), new_narrow.c_str() );
|
||||
}
|
||||
|
|
18
wutil.h
18
wutil.h
|
@ -1,7 +1,7 @@
|
|||
/** \file wutil.h
|
||||
|
||||
Prototypes for wide character equivalents of various standard unix
|
||||
functions.
|
||||
functions.
|
||||
*/
|
||||
#ifndef FISH_WUTIL_H
|
||||
#define FISH_WUTIL_H
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Wide version of the dirent data structure
|
||||
|
@ -24,8 +27,7 @@ struct wdirent
|
|||
The name of the current directory
|
||||
*/
|
||||
wchar_t *d_name;
|
||||
}
|
||||
;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -95,7 +97,7 @@ wchar_t *wgetcwd( wchar_t *buff, size_t sz );
|
|||
*/
|
||||
int wchdir( const wchar_t * dir );
|
||||
|
||||
/**
|
||||
/**
|
||||
Wide character version of realpath function. Just like the GNU
|
||||
version of realpath, wrealpath will accept 0 as the value for the
|
||||
second argument, in which case the result will be allocated using
|
||||
|
@ -106,17 +108,17 @@ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path);
|
|||
/**
|
||||
Wide character version of readdir()
|
||||
*/
|
||||
struct wdirent *wreaddir(DIR *dir );
|
||||
std::wstring *wreaddir(DIR *dir, std::wstring &outPath);
|
||||
|
||||
/**
|
||||
Wide character version of dirname()
|
||||
*/
|
||||
wchar_t *wdirname( wchar_t *path );
|
||||
std::wstring wdirname( const std::wstring &path);
|
||||
|
||||
/**
|
||||
Wide character version of basename()
|
||||
*/
|
||||
wchar_t *wbasename( const wchar_t *path );
|
||||
std::wstring wbasename( const std::wstring &path);
|
||||
|
||||
/**
|
||||
Wide character wrapper around the gettext function. For historic
|
||||
|
@ -141,6 +143,6 @@ int wmkdir( const wchar_t *dir, int mode );
|
|||
/**
|
||||
Wide character version of rename
|
||||
*/
|
||||
int wrename( const wchar_t *old, const wchar_t *new );
|
||||
int wrename( const wchar_t *oldName, const wchar_t *newName );
|
||||
|
||||
#endif
|
||||
|
|
46
xdgmime.cpp
46
xdgmime.cpp
|
@ -2,13 +2,13 @@
|
|||
/* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec.
|
||||
*
|
||||
* More info can be found at http://www.freedesktop.org/standards/
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2003,2004 Red Hat, Inc.
|
||||
* Copyright (C) 2003,2004 Jonathan Blandford <jrb@alum.mit.edu>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.0
|
||||
* Or under the following terms:
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
|
@ -93,7 +93,7 @@ xdg_dir_time_list_new (void)
|
|||
{
|
||||
XdgDirTimeList *retval;
|
||||
|
||||
retval = calloc (1, sizeof (XdgDirTimeList));
|
||||
retval = (XdgDirTimeList *)calloc (1, sizeof (XdgDirTimeList));
|
||||
retval->checked = XDG_CHECKED_UNCHECKED;
|
||||
|
||||
return retval;
|
||||
|
@ -122,7 +122,7 @@ xdg_mime_init_from_directory (const char *directory)
|
|||
|
||||
assert (directory != NULL);
|
||||
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||
if (stat (file_name, &st) == 0)
|
||||
{
|
||||
|
@ -139,7 +139,7 @@ xdg_mime_init_from_directory (const char *directory)
|
|||
free (file_name);
|
||||
}
|
||||
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
||||
if (stat (file_name, &st) == 0)
|
||||
{
|
||||
|
@ -156,12 +156,12 @@ xdg_mime_init_from_directory (const char *directory)
|
|||
free (file_name);
|
||||
}
|
||||
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/aliases") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/aliases") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/aliases");
|
||||
_xdg_mime_alias_read_from_file (alias_list, file_name);
|
||||
free (file_name);
|
||||
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/subclasses") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/subclasses") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/subclasses");
|
||||
_xdg_mime_parent_read_from_file (parent_list, file_name);
|
||||
free (file_name);
|
||||
|
@ -194,7 +194,7 @@ xdg_run_command_on_dirs (XdgDirectoryFunc func,
|
|||
char *guessed_xdg_home;
|
||||
int stop_processing;
|
||||
|
||||
guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1);
|
||||
guessed_xdg_home = (char *)malloc (strlen (home) + strlen ("/.local/share/") + 1);
|
||||
strcpy (guessed_xdg_home, home);
|
||||
strcat (guessed_xdg_home, "/.local/share/");
|
||||
stop_processing = (func) (guessed_xdg_home, user_data);
|
||||
|
@ -232,7 +232,7 @@ xdg_run_command_on_dirs (XdgDirectoryFunc func,
|
|||
len = end_ptr - ptr;
|
||||
else
|
||||
len = end_ptr - ptr + 1;
|
||||
dir = malloc (len + 1);
|
||||
dir = (char *)malloc (len + 1);
|
||||
strncpy (dir, ptr, len);
|
||||
dir[len] = '\0';
|
||||
stop_processing = (func) (dir, user_data);
|
||||
|
@ -290,7 +290,7 @@ xdg_check_dir (const char *directory,
|
|||
assert (directory != NULL);
|
||||
|
||||
/* Check the globs file */
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||
invalid = xdg_check_file (file_name);
|
||||
free (file_name);
|
||||
|
@ -301,7 +301,7 @@ xdg_check_dir (const char *directory,
|
|||
}
|
||||
|
||||
/* Check the magic file */
|
||||
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||
file_name = (char *)malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
||||
invalid = xdg_check_file (file_name);
|
||||
free (file_name);
|
||||
|
@ -437,10 +437,10 @@ xdg_mime_get_mime_type_for_file (const char *file_name)
|
|||
* be large and need getting from a stream instead of just reading it all
|
||||
* in. */
|
||||
max_extent = _xdg_mime_magic_get_buffer_extents (global_magic);
|
||||
data = malloc (max_extent);
|
||||
data = (unsigned char *)malloc (max_extent);
|
||||
if (data == NULL)
|
||||
return XDG_MIME_TYPE_UNKNOWN;
|
||||
|
||||
|
||||
file = fopen (file_name, "r");
|
||||
if (file == NULL)
|
||||
{
|
||||
|
@ -500,7 +500,7 @@ xdg_mime_shutdown (void)
|
|||
xdg_dir_time_list_free (dir_time_list);
|
||||
dir_time_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (global_hash)
|
||||
{
|
||||
_xdg_glob_hash_free (global_hash);
|
||||
|
@ -522,8 +522,8 @@ xdg_mime_shutdown (void)
|
|||
{
|
||||
_xdg_mime_parent_list_free ( parent_list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for (list = callback_list; list; list = list->next)
|
||||
(list->callback) (list->data);
|
||||
|
||||
|
@ -534,7 +534,7 @@ int
|
|||
xdg_mime_get_max_buffer_extents (void)
|
||||
{
|
||||
xdg_mime_init ();
|
||||
|
||||
|
||||
return _xdg_mime_magic_get_buffer_extents (global_magic);
|
||||
}
|
||||
|
||||
|
@ -577,7 +577,7 @@ xdg_mime_media_type_equal (const char *mime_a,
|
|||
xdg_mime_init ();
|
||||
|
||||
sep = strchr (mime_a, '/');
|
||||
|
||||
|
||||
if (sep && strncmp (mime_a, mime_b, sep - mime_a + 1) == 0)
|
||||
return 1;
|
||||
|
||||
|
@ -616,7 +616,7 @@ xdg_mime_mime_type_subclass (const char *mime,
|
|||
if (strcmp (umime, ubase) == 0)
|
||||
return 1;
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
/* Handle supertypes */
|
||||
if (xdg_mime_is_super_type (ubase) &&
|
||||
xdg_mime_media_type_equal (umime, ubase))
|
||||
|
@ -624,13 +624,13 @@ xdg_mime_mime_type_subclass (const char *mime,
|
|||
#endif
|
||||
|
||||
/* Handle special cases text/plain and application/octet-stream */
|
||||
if (strcmp (ubase, "text/plain") == 0 &&
|
||||
if (strcmp (ubase, "text/plain") == 0 &&
|
||||
strncmp (umime, "text/", 5) == 0)
|
||||
return 1;
|
||||
|
||||
if (strcmp (ubase, "application/octet-stream") == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
parents = _xdg_mime_parent_list_lookup (parent_list, umime);
|
||||
for (; parents && *parents; parents++)
|
||||
{
|
||||
|
@ -653,7 +653,7 @@ xdg_mime_get_mime_parents (const char *mime)
|
|||
return _xdg_mime_parent_list_lookup (parent_list, umime);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
xdg_mime_dump (void)
|
||||
{
|
||||
printf ("*** ALIASES ***\n\n");
|
||||
|
@ -674,7 +674,7 @@ xdg_mime_register_reload_callback (XdgMimeCallback callback,
|
|||
static int callback_id = 1;
|
||||
|
||||
/* Make a new list element */
|
||||
list_el = calloc (1, sizeof (XdgCallbackList));
|
||||
list_el = (XdgCallbackList *)calloc (1, sizeof (XdgCallbackList));
|
||||
list_el->callback_id = callback_id;
|
||||
list_el->callback = callback;
|
||||
list_el->data = data;
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
/* xdgmime.h: XDG Mime Spec mime resolver. Based on version 0.11 of the spec.
|
||||
*
|
||||
* More info can be found at http://www.freedesktop.org/standards/
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2003 Red Hat, Inc.
|
||||
* Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.0
|
||||
* Or under the following terms:
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
|
@ -44,7 +44,7 @@ extern "C" {
|
|||
typedef void (*XdgMimeCallback) (void *user_data);
|
||||
typedef void (*XdgMimeDestroy) (void *user_data);
|
||||
|
||||
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data)
|
||||
#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file)
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
typedef struct XdgAlias XdgAlias;
|
||||
|
||||
struct XdgAlias
|
||||
struct XdgAlias
|
||||
{
|
||||
char *alias;
|
||||
char *mime_type;
|
||||
|
@ -64,7 +64,7 @@ _xdg_mime_alias_list_new (void)
|
|||
{
|
||||
XdgAliasList *list;
|
||||
|
||||
list = malloc (sizeof (XdgAliasList));
|
||||
list = (XdgAliasList *)malloc (sizeof (XdgAliasList));
|
||||
|
||||
list->aliases = NULL;
|
||||
list->n_aliases = 0;
|
||||
|
@ -72,7 +72,7 @@ _xdg_mime_alias_list_new (void)
|
|||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
_xdg_mime_alias_list_free (XdgAliasList *list)
|
||||
{
|
||||
int i;
|
||||
|
@ -107,7 +107,7 @@ _xdg_mime_alias_list_lookup (XdgAliasList *list,
|
|||
key.alias = (char *)alias;
|
||||
key.mime_type = 0;
|
||||
|
||||
entry = bsearch (&key, list->aliases, list->n_aliases,
|
||||
entry = (XdgAlias *)bsearch (&key, list->aliases, list->n_aliases,
|
||||
sizeof (XdgAlias), alias_entry_cmp);
|
||||
if (entry)
|
||||
return entry->mime_type;
|
||||
|
@ -132,7 +132,7 @@ _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
|||
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
|
||||
* Blah */
|
||||
alloc = list->n_aliases + 16;
|
||||
list->aliases = realloc (list->aliases, alloc * sizeof (XdgAlias));
|
||||
list->aliases = (XdgAlias *)realloc (list->aliases, alloc * sizeof (XdgAlias));
|
||||
while (fgets (line, 255, file) != NULL)
|
||||
{
|
||||
char *sep;
|
||||
|
@ -147,20 +147,20 @@ _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
|||
if (list->n_aliases == alloc)
|
||||
{
|
||||
alloc <<= 1;
|
||||
list->aliases = realloc (list->aliases,
|
||||
list->aliases = (XdgAlias *)realloc (list->aliases,
|
||||
alloc * sizeof (XdgAlias));
|
||||
}
|
||||
list->aliases[list->n_aliases].alias = strdup (line);
|
||||
list->aliases[list->n_aliases].mime_type = strdup (sep);
|
||||
list->n_aliases++;
|
||||
}
|
||||
list->aliases = realloc (list->aliases,
|
||||
list->aliases = (XdgAlias *)realloc (list->aliases,
|
||||
list->n_aliases * sizeof (XdgAlias));
|
||||
|
||||
fclose (file);
|
||||
|
||||
fclose (file);
|
||||
|
||||
if (list->n_aliases > 1)
|
||||
qsort (list->aliases, list->n_aliases,
|
||||
qsort (list->aliases, list->n_aliases,
|
||||
sizeof (XdgAlias), alias_entry_cmp);
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ _xdg_mime_alias_list_dump (XdgAliasList *list)
|
|||
{
|
||||
for (i = 0; i < list->n_aliases; i++)
|
||||
{
|
||||
printf ("%s %s\n",
|
||||
printf ("%s %s\n",
|
||||
list->aliases[i].alias,
|
||||
list->aliases[i].mime_type);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ _xdg_glob_list_new (void)
|
|||
{
|
||||
XdgGlobList *new_element;
|
||||
|
||||
new_element = calloc (1, sizeof (XdgGlobList));
|
||||
new_element = (XdgGlobList *)calloc (1, sizeof (XdgGlobList));
|
||||
|
||||
return new_element;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ _xdg_glob_list_append (XdgGlobList *glob_list,
|
|||
XdgGlobList *tmp_element;
|
||||
|
||||
new_element = _xdg_glob_list_new ();
|
||||
new_element->data = data;
|
||||
new_element->data = (const char *)data;
|
||||
new_element->mime_type = mime_type;
|
||||
if (glob_list == NULL)
|
||||
return new_element;
|
||||
|
@ -152,7 +152,7 @@ _xdg_glob_hash_node_new (void)
|
|||
{
|
||||
XdgGlobHashNode *glob_hash_node;
|
||||
|
||||
glob_hash_node = calloc (1, sizeof (XdgGlobHashNode));
|
||||
glob_hash_node = (XdgGlobHashNode *)calloc (1, sizeof (XdgGlobHashNode));
|
||||
|
||||
return glob_hash_node;
|
||||
}
|
||||
|
@ -302,11 +302,11 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
|||
mime_type = (_xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, FALSE));
|
||||
if (mime_type != NULL)
|
||||
return mime_type;
|
||||
|
||||
|
||||
mime_type = (_xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, TRUE));
|
||||
if (mime_type != NULL)
|
||||
return mime_type;
|
||||
|
||||
|
||||
ptr = strchr (ptr+1, '.');
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ _xdg_glob_hash_new (void)
|
|||
{
|
||||
XdgGlobHash *glob_hash;
|
||||
|
||||
glob_hash = calloc (1, sizeof (XdgGlobHash));
|
||||
glob_hash = (XdgGlobHash *)calloc (1, sizeof (XdgGlobHash));
|
||||
|
||||
return glob_hash;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef enum
|
|||
XDG_GLOB_FULL /* x*.[ch] */
|
||||
} XdgGlobType;
|
||||
|
||||
|
||||
|
||||
#ifdef XDG_PREFIX
|
||||
#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file)
|
||||
#define _xdg_glob_hash_new XDG_ENTRY(hash_new)
|
||||
|
|
|
@ -91,7 +91,7 @@ struct XdgMimeMagic
|
|||
static XdgMimeMagicMatch *
|
||||
_xdg_mime_magic_match_new (void)
|
||||
{
|
||||
return calloc (1, sizeof (XdgMimeMagicMatch));
|
||||
return (XdgMimeMagicMatch *)calloc (1, sizeof (XdgMimeMagicMatch));
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,7 +100,7 @@ _xdg_mime_magic_matchlet_new (void)
|
|||
{
|
||||
XdgMimeMagicMatchlet *matchlet;
|
||||
|
||||
matchlet = malloc (sizeof (XdgMimeMagicMatchlet));
|
||||
matchlet = (XdgMimeMagicMatchlet *)malloc (sizeof (XdgMimeMagicMatchlet));
|
||||
|
||||
matchlet->indent = 0;
|
||||
matchlet->offset = 0;
|
||||
|
@ -166,7 +166,7 @@ _xdg_mime_magic_read_to_newline (FILE *magic_file,
|
|||
|
||||
len = 128;
|
||||
pos = 0;
|
||||
retval = malloc (len);
|
||||
retval = (char *)malloc (len);
|
||||
*end_of_file = FALSE;
|
||||
|
||||
while (TRUE)
|
||||
|
@ -183,7 +183,7 @@ _xdg_mime_magic_read_to_newline (FILE *magic_file,
|
|||
if (pos % 128 == 127)
|
||||
{
|
||||
len = len + 128;
|
||||
retval = realloc (retval, len);
|
||||
retval = (char *)realloc (retval, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ _xdg_mime_magic_parse_magic_line (FILE *magic_file,
|
|||
}
|
||||
matchlet->value_length = matchlet->value_length + (c & 0xFF);
|
||||
|
||||
matchlet->value = malloc (matchlet->value_length);
|
||||
matchlet->value = (unsigned char *)malloc (matchlet->value_length);
|
||||
|
||||
/* OOM */
|
||||
if (matchlet->value == NULL)
|
||||
|
@ -414,7 +414,7 @@ _xdg_mime_magic_parse_magic_line (FILE *magic_file,
|
|||
c = getc_unlocked (magic_file);
|
||||
if (c == '&')
|
||||
{
|
||||
matchlet->mask = malloc (matchlet->value_length);
|
||||
matchlet->mask = (unsigned char *)malloc (matchlet->value_length);
|
||||
/* OOM */
|
||||
if (matchlet->mask == NULL)
|
||||
{
|
||||
|
@ -633,7 +633,7 @@ _xdg_mime_magic_insert_match (XdgMimeMagic *mime_magic,
|
|||
XdgMimeMagic *
|
||||
_xdg_mime_magic_new (void)
|
||||
{
|
||||
return calloc (1, sizeof (XdgMimeMagic));
|
||||
return (XdgMimeMagic *)calloc (1, sizeof (XdgMimeMagic));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -65,7 +65,7 @@ _xdg_mime_parent_list_new (void)
|
|||
{
|
||||
XdgParentList *list;
|
||||
|
||||
list = malloc (sizeof (XdgParentList));
|
||||
list = (XdgParentList *)malloc (sizeof (XdgParentList));
|
||||
|
||||
list->parents = NULL;
|
||||
list->n_mimes = 0;
|
||||
|
@ -73,7 +73,7 @@ _xdg_mime_parent_list_new (void)
|
|||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
_xdg_mime_parent_list_free (XdgParentList *list)
|
||||
{
|
||||
int i;
|
||||
|
@ -112,7 +112,7 @@ _xdg_mime_parent_list_lookup (XdgParentList *list,
|
|||
key.mime = (char *)mime;
|
||||
key.parents = NULL;
|
||||
|
||||
entry = bsearch (&key, list->parents, list->n_mimes,
|
||||
entry = (XdgMimeParents *)bsearch (&key, list->parents, list->n_mimes,
|
||||
sizeof (XdgMimeParents), &parent_entry_cmp);
|
||||
if (entry)
|
||||
return (const char **)entry->parents;
|
||||
|
@ -138,7 +138,7 @@ _xdg_mime_parent_read_from_file (XdgParentList *list,
|
|||
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
|
||||
* Blah */
|
||||
alloc = list->n_mimes + 16;
|
||||
list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents));
|
||||
list->parents = (XdgMimeParents *)realloc (list->parents, alloc * sizeof (XdgMimeParents));
|
||||
while (fgets (line, 255, file) != NULL)
|
||||
{
|
||||
char *sep;
|
||||
|
@ -159,13 +159,13 @@ _xdg_mime_parent_read_from_file (XdgParentList *list,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
if (list->n_mimes == alloc)
|
||||
{
|
||||
alloc <<= 1;
|
||||
list->parents = realloc (list->parents,
|
||||
list->parents = (XdgMimeParents *)realloc (list->parents,
|
||||
alloc * sizeof (XdgMimeParents));
|
||||
}
|
||||
list->parents[list->n_mimes].mime = strdup (line);
|
||||
|
@ -177,30 +177,30 @@ _xdg_mime_parent_read_from_file (XdgParentList *list,
|
|||
if (!entry->parents)
|
||||
{
|
||||
entry->n_parents = 1;
|
||||
entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *));
|
||||
entry->parents = (char **)malloc ((entry->n_parents + 1) * sizeof (char *));
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->n_parents += 1;
|
||||
entry->parents = realloc (entry->parents,
|
||||
entry->parents = (char **)realloc (entry->parents,
|
||||
(entry->n_parents + 2) * sizeof (char *));
|
||||
}
|
||||
entry->parents[entry->n_parents - 1] = strdup (sep);
|
||||
entry->parents[entry->n_parents] = NULL;
|
||||
}
|
||||
|
||||
list->parents = realloc (list->parents,
|
||||
list->parents = (XdgMimeParents *)realloc (list->parents,
|
||||
list->n_mimes * sizeof (XdgMimeParents));
|
||||
|
||||
fclose (file);
|
||||
|
||||
fclose (file);
|
||||
|
||||
if (list->n_mimes > 1)
|
||||
qsort (list->parents, list->n_mimes,
|
||||
qsort (list->parents, list->n_mimes,
|
||||
sizeof (XdgMimeParents), &parent_entry_cmp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
_xdg_mime_parent_list_dump (XdgParentList *list)
|
||||
{
|
||||
int i;
|
||||
|
|
Loading…
Reference in a new issue