]>
git.saurik.com Git - apt.git/blob - apt-private/private-output.cc
1 // Include files /*{{{*/
4 #include <apt-pkg/configuration.h>
5 #include <apt-pkg/strutl.h>
6 #include <apt-pkg/error.h>
7 #include <apt-pkg/cachefile.h>
8 #include <apt-pkg/pkgrecords.h>
9 #include <apt-pkg/policy.h>
10 #include <apt-pkg/depcache.h>
11 #include <apt-pkg/pkgcache.h>
12 #include <apt-pkg/cacheiterators.h>
14 #include <apt-private/private-output.h>
15 #include <apt-private/private-cachefile.h>
32 std::ostream
c0out(0);
33 std::ostream
c1out(0);
34 std::ostream
c2out(0);
35 std::ofstream
devnull("/dev/null");
38 unsigned int ScreenWidth
= 80 - 1; /* - 1 for the cursor */
40 // SigWinch - Window size change signal handler /*{{{*/
41 // ---------------------------------------------------------------------
43 static void SigWinch(int)
49 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
50 ScreenWidth
= ws
.ws_col
- 1;
54 bool InitOutput() /*{{{*/
56 if (!isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
57 _config
->Set("quiet","1");
59 c0out
.rdbuf(cout
.rdbuf());
60 c1out
.rdbuf(cout
.rdbuf());
61 c2out
.rdbuf(cout
.rdbuf());
62 if (_config
->FindI("quiet",0) > 0)
63 c0out
.rdbuf(devnull
.rdbuf());
64 if (_config
->FindI("quiet",0) > 1)
65 c1out
.rdbuf(devnull
.rdbuf());
67 // deal with window size changes
68 signal(SIGWINCH
,SigWinch
);
73 _config
->Set("APT::Color", "false");
74 _config
->Set("APT::Color::Highlight", "");
75 _config
->Set("APT::Color::Neutral", "");
78 _config
->CndSet("APT::Color::Highlight", "\x1B[32m");
79 _config
->CndSet("APT::Color::Neutral", "\x1B[0m");
81 _config
->CndSet("APT::Color::Red", "\x1B[31m");
82 _config
->CndSet("APT::Color::Green", "\x1B[32m");
83 _config
->CndSet("APT::Color::Yellow", "\x1B[33m");
84 _config
->CndSet("APT::Color::Blue", "\x1B[34m");
85 _config
->CndSet("APT::Color::Magenta", "\x1B[35m");
86 _config
->CndSet("APT::Color::Cyan", "\x1B[36m");
87 _config
->CndSet("APT::Color::White", "\x1B[37m");
93 static std::string
GetArchiveSuite(pkgCacheFile
&/*CacheFile*/, pkgCache::VerIterator ver
) /*{{{*/
95 std::string suite
= "";
96 if (ver
&& ver
.FileList() && ver
.FileList())
98 pkgCache::VerFileIterator VF
= ver
.FileList();
99 for (; VF
.end() == false ; ++VF
)
101 if(VF
.File() == NULL
|| VF
.File().Archive() == NULL
)
102 suite
= suite
+ "," + _("unknown");
104 suite
= suite
+ "," + VF
.File().Archive();
105 //suite = VF.File().Archive();
107 suite
= suite
.erase(0, 1);
112 static std::string
GetFlagsStr(pkgCacheFile
&CacheFile
, pkgCache::PkgIterator P
)/*{{{*/
114 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
115 pkgDepCache::StateCache
&state
= (*DepCache
)[P
];
117 std::string flags_str
;
118 if (state
.NowBroken())
120 if (P
.CurrentVer() && state
.Upgradable())
122 else if (P
.CurrentVer() != NULL
)
129 static std::string
GetCandidateVersion(pkgCacheFile
&CacheFile
, pkgCache::PkgIterator P
)/*{{{*/
131 pkgPolicy
*policy
= CacheFile
.GetPolicy();
132 pkgCache::VerIterator cand
= policy
->GetCandidateVer(P
);
134 return cand
? cand
.VerStr() : "(none)";
137 static std::string
GetInstalledVersion(pkgCacheFile
&/*CacheFile*/, pkgCache::PkgIterator P
)/*{{{*/
139 pkgCache::VerIterator inst
= P
.CurrentVer();
141 return inst
? inst
.VerStr() : "(none)";
144 static std::string
GetVersion(pkgCacheFile
&/*CacheFile*/, pkgCache::VerIterator V
)/*{{{*/
146 pkgCache::PkgIterator P
= V
.ParentPkg();
147 if (V
== P
.CurrentVer())
149 std::string inst_str
= DeNull(V
.VerStr());
150 #if 0 // FIXME: do we want this or something like this?
151 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
152 pkgDepCache::StateCache
&state
= (*DepCache
)[P
];
153 if (state
.Upgradable())
154 return "**"+inst_str
;
160 return DeNull(V
.VerStr());
164 static std::string
GetArchitecture(pkgCacheFile
&CacheFile
, pkgCache::PkgIterator P
)/*{{{*/
166 pkgPolicy
*policy
= CacheFile
.GetPolicy();
167 pkgCache::VerIterator inst
= P
.CurrentVer();
168 pkgCache::VerIterator cand
= policy
->GetCandidateVer(P
);
170 // this may happen for packages in dpkg "deinstall ok config-file" state
171 if (inst
.IsGood() == false && cand
.IsGood() == false)
172 return P
.VersionList().Arch();
174 return inst
? inst
.Arch() : cand
.Arch();
177 static std::string
GetShortDescription(pkgCacheFile
&CacheFile
, pkgRecords
&records
, pkgCache::PkgIterator P
)/*{{{*/
179 pkgPolicy
*policy
= CacheFile
.GetPolicy();
181 pkgCache::VerIterator ver
;
183 ver
= P
.CurrentVer();
185 ver
= policy
->GetCandidateVer(P
);
187 std::string ShortDescription
= "(none)";
190 pkgCache::DescIterator Desc
= ver
.TranslatedDescription();
191 pkgRecords::Parser
& parser
= records
.Lookup(Desc
.FileList());
193 ShortDescription
= parser
.ShortDesc();
195 return ShortDescription
;
198 void ListSingleVersion(pkgCacheFile
&CacheFile
, pkgRecords
&records
, /*{{{*/
199 pkgCache::VerIterator V
, std::ostream
&out
,
200 bool include_summary
)
202 pkgCache::PkgIterator P
= V
.ParentPkg();
204 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
205 pkgDepCache::StateCache
&state
= (*DepCache
)[P
];
207 std::string suite
= GetArchiveSuite(CacheFile
, V
);
208 std::string name_str
= P
.Name();
210 if (_config
->FindB("APT::Cmd::use-format", false))
212 std::string format
= _config
->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}");
213 std::string output
= format
;
215 output
= SubstVar(output
, "${db::Status-Abbrev}", GetFlagsStr(CacheFile
, P
));
216 output
= SubstVar(output
, "${Package}", name_str
);
217 output
= SubstVar(output
, "${installed:Version}", GetInstalledVersion(CacheFile
, P
));
218 output
= SubstVar(output
, "${candidate:Version}", GetCandidateVersion(CacheFile
, P
));
219 output
= SubstVar(output
, "${Version}", GetVersion(CacheFile
, V
));
220 output
= SubstVar(output
, "${Description}", GetShortDescription(CacheFile
, records
, P
));
221 output
= SubstVar(output
, "${Origin}", GetArchiveSuite(CacheFile
, V
));
222 out
<< output
<< std::endl
;
224 // raring/linux-kernel version [upradable: new-version]
226 pkgPolicy
*policy
= CacheFile
.GetPolicy();
227 std::string VersionStr
= GetVersion(CacheFile
, V
);
228 std::string CandidateVerStr
= GetCandidateVersion(CacheFile
, P
);
229 std::string InstalledVerStr
= GetInstalledVersion(CacheFile
, P
);
230 std::string StatusStr
;
231 if(P
.CurrentVer() == V
&& state
.Upgradable()) {
232 strprintf(StatusStr
, _("[installed,upgradable to: %s]"),
233 CandidateVerStr
.c_str());
234 } else if (P
.CurrentVer() == V
) {
235 if(!V
.Downloadable())
236 StatusStr
= _("[installed,local]");
238 if(V
.Automatic() && state
.Garbage
)
239 StatusStr
= _("[installed,auto-removable]");
240 else if (state
.Flags
& pkgCache::Flag::Auto
)
241 StatusStr
= _("[installed,automatic]");
243 StatusStr
= _("[installed]");
244 } else if (P
.CurrentVer() &&
245 policy
->GetCandidateVer(P
) == V
&&
246 state
.Upgradable()) {
247 strprintf(StatusStr
, _("[upgradable from: %s]"),
248 InstalledVerStr
.c_str());
250 if (V
.ParentPkg()->CurrentState
== pkgCache::State::ConfigFiles
)
251 StatusStr
= _("[residual-config]");
255 out
<< std::setiosflags(std::ios::left
)
256 << _config
->Find("APT::Color::Highlight", "")
258 << _config
->Find("APT::Color::Neutral", "")
262 << GetArchitecture(CacheFile
, P
);
264 out
<< " " << StatusStr
;
268 << " " << GetShortDescription(CacheFile
, records
, P
)
274 // ShowList - Show a list /*{{{*/
275 // ---------------------------------------------------------------------
276 /* This prints out a string of space separated words with a title and
277 a two space indent line wraped to the current screen width. */
278 bool ShowList(ostream
&out
,string Title
,string List
,string VersionsList
)
280 if (List
.empty() == true)
282 // trim trailing space
283 int NonSpace
= List
.find_last_not_of(' ');
286 List
= List
.erase(NonSpace
+ 1);
287 if (List
.empty() == true)
291 // Acount for the leading space
292 int ScreenWidth
= ::ScreenWidth
- 3;
294 out
<< Title
<< endl
;
295 string::size_type Start
= 0;
296 string::size_type VersionsStart
= 0;
297 while (Start
< List
.size())
299 if(_config
->FindB("APT::Get::Show-Versions",false) == true &&
300 VersionsList
.size() > 0) {
301 string::size_type End
;
302 string::size_type VersionsEnd
;
304 End
= List
.find(' ',Start
);
305 VersionsEnd
= VersionsList
.find('\n', VersionsStart
);
307 out
<< " " << string(List
,Start
,End
- Start
) << " (" <<
308 string(VersionsList
,VersionsStart
,VersionsEnd
- VersionsStart
) <<
311 if (End
== string::npos
|| End
< Start
)
312 End
= Start
+ ScreenWidth
;
315 VersionsStart
= VersionsEnd
+ 1;
317 string::size_type End
;
319 if (Start
+ ScreenWidth
>= List
.size())
322 End
= List
.rfind(' ',Start
+ScreenWidth
);
324 if (End
== string::npos
|| End
< Start
)
325 End
= Start
+ ScreenWidth
;
326 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
334 // ShowBroken - Debugging aide /*{{{*/
335 // ---------------------------------------------------------------------
336 /* This prints out the names of all the packages that are broken along
337 with the name of each each broken dependency and a quite version
340 The output looks like:
341 The following packages have unmet dependencies:
342 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
343 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
344 Depends: libsasl7 but it is not going to be installed
346 void ShowBroken(ostream
&out
,CacheFile
&Cache
,bool Now
)
348 if (Cache
->BrokenCount() == 0)
351 out
<< _("The following packages have unmet dependencies:") << endl
;
352 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
354 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
358 if (Cache
[I
].NowBroken() == false)
363 if (Cache
[I
].InstBroken() == false)
367 // Print out each package and the failed dependencies
368 out
<< " " << I
.FullName(true) << " :";
369 unsigned const Indent
= I
.FullName(true).size() + 3;
371 pkgCache::VerIterator Ver
;
374 Ver
= I
.CurrentVer();
376 Ver
= Cache
[I
].InstVerIter(Cache
);
378 if (Ver
.end() == true)
384 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false;)
386 // Compute a single dependency element (glob or)
387 pkgCache::DepIterator Start
;
388 pkgCache::DepIterator End
;
389 D
.GlobOr(Start
,End
); // advances D
391 if (Cache
->IsImportantDep(End
) == false)
396 if ((Cache
[End
] & pkgDepCache::DepGNow
) == pkgDepCache::DepGNow
)
401 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
409 for (unsigned J
= 0; J
!= Indent
; J
++)
413 if (FirstOr
== false)
415 for (unsigned J
= 0; J
!= strlen(End
.DepType()) + 3; J
++)
419 out
<< ' ' << End
.DepType() << ": ";
422 out
<< Start
.TargetPkg().FullName(true);
424 // Show a quick summary of the version requirements
425 if (Start
.TargetVer() != 0)
426 out
<< " (" << Start
.CompType() << " " << Start
.TargetVer() << ")";
428 /* Show a summary of the target package if possible. In the case
429 of virtual packages we show nothing */
430 pkgCache::PkgIterator Targ
= Start
.TargetPkg();
431 if (Targ
->ProvidesList
== 0)
434 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
436 Ver
= Targ
.CurrentVer();
438 if (Ver
.end() == false)
441 ioprintf(out
,_("but %s is installed"),Ver
.VerStr());
443 ioprintf(out
,_("but %s is to be installed"),Ver
.VerStr());
447 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
449 if (Targ
->ProvidesList
== 0)
450 out
<< _("but it is not installable");
452 out
<< _("but it is a virtual package");
455 out
<< (Now
?_("but it is not installed"):_("but it is not going to be installed"));
471 // ShowNew - Show packages to newly install /*{{{*/
472 // ---------------------------------------------------------------------
474 void ShowNew(ostream
&out
,CacheFile
&Cache
)
476 /* Print out a list of packages that are going to be installed extra
477 to what the user asked */
480 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
482 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
483 if (Cache
[I
].NewInstall() == true) {
484 List
+= I
.FullName(true) + " ";
485 VersionsList
+= string(Cache
[I
].CandVersion
) + "\n";
489 ShowList(out
,_("The following NEW packages will be installed:"),List
,VersionsList
);
492 // ShowDel - Show packages to delete /*{{{*/
493 // ---------------------------------------------------------------------
495 void ShowDel(ostream
&out
,CacheFile
&Cache
)
497 /* Print out a list of packages that are going to be removed extra
498 to what the user asked */
501 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
503 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
504 if (Cache
[I
].Delete() == true)
506 if ((Cache
[I
].iFlags
& pkgDepCache::Purge
) == pkgDepCache::Purge
)
507 List
+= I
.FullName(true) + "* ";
509 List
+= I
.FullName(true) + " ";
511 VersionsList
+= string(Cache
[I
].CandVersion
)+ "\n";
515 ShowList(out
,_("The following packages will be REMOVED:"),List
,VersionsList
);
518 // ShowKept - Show kept packages /*{{{*/
519 // ---------------------------------------------------------------------
521 void ShowKept(ostream
&out
,CacheFile
&Cache
)
525 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
527 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
530 if (Cache
[I
].Upgrade() == true || Cache
[I
].Upgradable() == false ||
531 I
->CurrentVer
== 0 || Cache
[I
].Delete() == true)
534 List
+= I
.FullName(true) + " ";
535 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
537 ShowList(out
,_("The following packages have been kept back:"),List
,VersionsList
);
540 // ShowUpgraded - Show upgraded packages /*{{{*/
541 // ---------------------------------------------------------------------
543 void ShowUpgraded(ostream
&out
,CacheFile
&Cache
)
547 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
549 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
552 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
555 List
+= I
.FullName(true) + " ";
556 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
558 ShowList(out
,_("The following packages will be upgraded:"),List
,VersionsList
);
561 // ShowDowngraded - Show downgraded packages /*{{{*/
562 // ---------------------------------------------------------------------
564 bool ShowDowngraded(ostream
&out
,CacheFile
&Cache
)
568 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
570 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
573 if (Cache
[I
].Downgrade() == false || Cache
[I
].NewInstall() == true)
576 List
+= I
.FullName(true) + " ";
577 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
579 return ShowList(out
,_("The following packages will be DOWNGRADED:"),List
,VersionsList
);
582 // ShowHold - Show held but changed packages /*{{{*/
583 // ---------------------------------------------------------------------
585 bool ShowHold(ostream
&out
,CacheFile
&Cache
)
589 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
591 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
592 if (Cache
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
593 I
->SelectedState
== pkgCache::State::Hold
) {
594 List
+= I
.FullName(true) + " ";
595 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
599 return ShowList(out
,_("The following held packages will be changed:"),List
,VersionsList
);
602 // ShowEssential - Show an essential package warning /*{{{*/
603 // ---------------------------------------------------------------------
604 /* This prints out a warning message that is not to be ignored. It shows
605 all essential packages and their dependents that are to be removed.
606 It is insanely risky to remove the dependents of an essential package! */
607 bool ShowEssential(ostream
&out
,CacheFile
&Cache
)
611 bool *Added
= new bool[Cache
->Head().PackageCount
];
612 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
615 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
617 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
618 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
619 (I
->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
)
622 // The essential package is being removed
623 if (Cache
[I
].Delete() == true)
625 if (Added
[I
->ID
] == false)
628 List
+= I
.FullName(true) + " ";
629 //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
635 if (I
->CurrentVer
== 0)
638 // Print out any essential package depenendents that are to be removed
639 for (pkgCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; ++D
)
641 // Skip everything but depends
642 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
643 D
->Type
!= pkgCache::Dep::Depends
)
646 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
647 if (Cache
[P
].Delete() == true)
649 if (Added
[P
->ID
] == true)
654 snprintf(S
,sizeof(S
),_("%s (due to %s) "),P
.FullName(true).c_str(),I
.FullName(true).c_str());
656 //VersionsList += "\n"; ???
662 return ShowList(out
,_("WARNING: The following essential packages will be removed.\n"
663 "This should NOT be done unless you know exactly what you are doing!"),List
,VersionsList
);
667 // Stats - Show some statistics /*{{{*/
668 // ---------------------------------------------------------------------
670 void Stats(ostream
&out
,pkgDepCache
&Dep
)
672 unsigned long Upgrade
= 0;
673 unsigned long Downgrade
= 0;
674 unsigned long Install
= 0;
675 unsigned long ReInstall
= 0;
676 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; ++I
)
678 if (Dep
[I
].NewInstall() == true)
682 if (Dep
[I
].Upgrade() == true)
685 if (Dep
[I
].Downgrade() == true)
689 if (Dep
[I
].Delete() == false && (Dep
[I
].iFlags
& pkgDepCache::ReInstall
) == pkgDepCache::ReInstall
)
693 ioprintf(out
,_("%lu upgraded, %lu newly installed, "),
697 ioprintf(out
,_("%lu reinstalled, "),ReInstall
);
699 ioprintf(out
,_("%lu downgraded, "),Downgrade
);
701 ioprintf(out
,_("%lu to remove and %lu not upgraded.\n"),
702 Dep
.DelCount(),Dep
.KeepCount());
704 if (Dep
.BadCount() != 0)
705 ioprintf(out
,_("%lu not fully installed or removed.\n"),
709 // YnPrompt - Yes No Prompt. /*{{{*/
710 // ---------------------------------------------------------------------
711 /* Returns true on a Yes.*/
712 bool YnPrompt(bool Default
)
714 /* nl_langinfo does not support LANGUAGE setting, so we unset it here
715 to have the help-message (hopefully) match the expected characters */
716 char * language
= getenv("LANGUAGE");
717 if (language
!= NULL
)
718 language
= strdup(language
);
719 if (language
!= NULL
)
720 unsetenv("LANGUAGE");
723 // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
724 // e.g. "Do you want to continue? [Y/n] "
725 // The user has to answer with an input matching the
726 // YESEXPR/NOEXPR defined in your l10n.
727 c2out
<< " " << _("[Y/n]") << " " << std::flush
;
729 // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
730 // e.g. "Should this file be removed? [y/N] "
731 // The user has to answer with an input matching the
732 // YESEXPR/NOEXPR defined in your l10n.
733 c2out
<< " " << _("[y/N]") << " " << std::flush
;
735 if (language
!= NULL
)
737 setenv("LANGUAGE", language
, 0);
741 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
743 // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
744 c1out
<< _("Y") << std::endl
;
747 else if (_config
->FindB("APT::Get::Assume-No",false) == true)
749 // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
750 c1out
<< _("N") << std::endl
;
754 char response
[1024] = "";
755 std::cin
.getline(response
, sizeof(response
));
760 if (strlen(response
) == 0)
766 Res
= regcomp(&Pattern
, nl_langinfo(YESEXPR
),
767 REG_EXTENDED
|REG_ICASE
|REG_NOSUB
);
771 regerror(Res
,&Pattern
,Error
,sizeof(Error
));
772 return _error
->Error(_("Regex compilation error - %s"),Error
);
775 Res
= regexec(&Pattern
, response
, 0, NULL
, 0);
781 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
782 // ---------------------------------------------------------------------
783 /* Returns true on a Yes.*/
784 bool AnalPrompt(const char *Text
)
787 std::cin
.getline(Buf
,sizeof(Buf
));
788 if (strcmp(Buf
,Text
) == 0)