I have a variable containing some basic aidl code (basically just a bunch of method signatures).
And I would like to echo that variable in a way that syntax highlighting is added to it. For example to display method names, data types and parameter names in different colors.
I know it can be done by hand like this:
NC='\033[0m' # no color
BLUE='\033[0;34m'
RED='\033[0;31m'
GREEN='\033[0;32m'
# Wihtout syntax highlighting
echo "void verifyIntentFilter(int id, int verificationCode, in List<String> failedDomains);"
# With syntax highlighting
echo "${BLUE}void${NC} ${RED}verifyIntentFilter${NC}(${BLUE}int${NC} ${GREEN}id${NC}, ${BLUE}int${NC} ${GREEN}verificationCode${NC}, ${BLUE}in List<String>${NC} ${GREEN}failedDomains${NC});"
But there are tens of thousands of lines of code that change all the time and I wouldn't want to rewrite the script all the time. Is there a Bash command to do this? I think if there is a command that can highlight Java or C++ code, that would probably work because the aidl method signatures are very similar.
Here is an example of my variable:
CODE=$(cat <<-END
void checkPackageStartable(String packageName, int userId);
boolean isPackageAvailable(String packageName, int userId);
PackageInfo getPackageInfo(String packageName, int flags, int userId);
PackageInfo getPackageInfoVersioned(in VersionedPackage versionedPackage,int flags, int userId);
int getPackageUid(String packageName, int flags, int userId);
int[] getPackageGids(String packageName, int flags, int userId);
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
PermissionInfo getPermissionInfo(String name, String packageName, int flags);
ParceledListSlice queryPermissionsByGroup(String group, int flags);
PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
ParceledListSlice getAllPermissionGroups(int flags);
ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId);
ActivityInfo getActivityInfo(in ComponentName className, int flags, int userId);
boolean activitySupportsIntent(in ComponentName className, in Intent intent,String resolvedType);
ActivityInfo getReceiverInfo(in ComponentName className, int flags, int userId);
ServiceInfo getServiceInfo(in ComponentName className, int flags, int userId);
ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
int checkPermission(String permName, String pkgName, int userId);
int checkUidPermission(String permName, int uid);
boolean addPermission(in PermissionInfo info);
void removePermission(String name);
void grantRuntimePermission(String packageName, String permissionName, int userId);
void revokeRuntimePermission(String packageName, String permissionName, int userId);
void resetRuntimePermissions();
int getPermissionFlags(String permissionName, String packageName, int userId);
void updatePermissionFlags(String permissionName, String packageName, int flagMask,int flagValues, int userId);
void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
boolean shouldShowRequestPermissionRationale(String permissionName,String packageName, int userId);
boolean isProtectedBroadcast(String actionName);
int checkSignatures(String pkg1, String pkg2);
int checkUidSignatures(int uid1, int uid2);
List<String> getAllPackages();
String[] getPackagesForUid(int uid);
String getNameForUid(int uid);
String[] getNamesForUids(in int[] uids);
int getUidForSharedUser(String sharedUserName);
int getFlagsForUid(int uid);
int getPrivateFlagsForUid(int uid);
boolean isUidPrivileged(int uid);
String[] getAppOpPermissionPackages(String permissionName);
ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
ResolveInfo findPersistentPreferredActivity(in Intent intent, int userId);
boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId);
ParceledListSlice queryIntentActivities(in Intent intent,String resolvedType, int flags, int userId);
ParceledListSlice queryIntentActivityOptions(in ComponentName caller, in Intent[] specifics,in String[] specificTypes, in Intent intent,String resolvedType, int flags, int userId);
ParceledListSlice queryIntentReceivers(in Intent intent,String resolvedType, int flags, int userId);
ResolveInfo resolveService(in Intent intent,String resolvedType, int flags, int userId);
ParceledListSlice queryIntentServices(in Intent intent,String resolvedType, int flags, int userId);
ParceledListSlice queryIntentContentProviders(in Intent intent,String resolvedType, int flags, int userId);
ParceledListSlice getInstalledPackages(int flags, in int userId);
ParceledListSlice getPackagesHoldingPermissions(in String[] permissions,int flags, int userId);
ParceledListSlice getInstalledApplications(int flags, int userId);
ParceledListSlice getPersistentApplications(int flags);
ProviderInfo resolveContentProvider(String name, int flags, int userId);
void querySyncProviders(inout List<String> outNames,inout List<ProviderInfo> outInfo);
ParceledListSlice queryContentProviders(String processName, int uid, int flags, String metaDataKey);
InstrumentationInfo getInstrumentationInfo(in ComponentName className, int flags);
ParceledListSlice queryInstrumentation(String targetPackage, int flags);
void finishPackageInstall(int token, boolean didLaunch);
void setInstallerPackageName(in String targetPackage, in String installerPackageName);
void setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName);
void deletePackageAsUser(in String packageName, int versionCode,IPackageDeleteObserver observer, int userId, int flags);
void deletePackageVersioned(in VersionedPackage versionedPackage,IPackageDeleteObserver2 observer, int userId, int flags);
String getInstallerPackageName(in String packageName);
void resetApplicationPreferences(int userId);
ResolveInfo getLastChosenActivity(in Intent intent,String resolvedType, int flags);
void setLastChosenActivity(in Intent intent, String resolvedType, int flags,in IntentFilter filter, int match, in ComponentName activity);
void addPreferredActivity(in IntentFilter filter, int match,in ComponentName[] set, in ComponentName activity, int userId);
void replacePreferredActivity(in IntentFilter filter, int match,in ComponentName[] set, in ComponentName activity, int userId);
void clearPackagePreferredActivities(String packageName);
int getPreferredActivities(out List<IntentFilter> outFilters,out List<ComponentName> outActivities, String packageName);
void addPersistentPreferredActivity(in IntentFilter filter, in ComponentName activity, int userId);
void clearPackagePersistentPreferredActivities(String packageName, int userId);
void addCrossProfileIntentFilter(in IntentFilter intentFilter, String ownerPackage,int sourceUserId, int targetUserId, int flags);
void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage);
String[] setPackagesSuspendedAsUser(in String[] packageNames, boolean suspended,in PersistableBundle appExtras, in PersistableBundle launcherExtras,String dialogMessage, String callingPackage, int userId);
boolean isPackageSuspendedForUser(String packageName, int userId);
PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId);
byte[] getPreferredActivityBackup(int userId);
void restorePreferredActivities(in byte[] backup, int userId);
byte[] getDefaultAppsBackup(int userId);
void restoreDefaultApps(in byte[] backup, int userId);
byte[] getIntentFilterVerificationBackup(int userId);
void restoreIntentFilterVerification(in byte[] backup, int userId);
byte[] getPermissionGrantBackup(int userId);
void restorePermissionGrants(in byte[] backup, int userId);
ComponentName getHomeActivities(out List<ResolveInfo> outHomeCandidates);
void setHomeActivity(in ComponentName className, int userId);
void setComponentEnabledSetting(in ComponentName componentName,in int newState, in int flags, int userId);
int getComponentEnabledSetting(in ComponentName componentName, int userId);
void setApplicationEnabledSetting(in String packageName, in int newState, int flags,int userId, String callingPackage);
int getApplicationEnabledSetting(in String packageName, int userId);
void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile,int pid);
void flushPackageRestrictionsAsUser(in int userId);
void setPackageStoppedState(String packageName, boolean stopped, int userId);
void freeStorageAndNotify(in String volumeUuid, in long freeStorageSize,int storageFlags, IPackageDataObserver observer);
void freeStorage(in String volumeUuid, in long freeStorageSize,int storageFlags, in IntentSender pi);
void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
void deleteApplicationCacheFilesAsUser(in String packageName, int userId, IPackageDataObserver observer);
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
void clearApplicationProfileData(in String packageName);
void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer);
String[] getSystemSharedLibraryNames();
ParceledListSlice getSystemAvailableFeatures();
boolean hasSystemFeature(String name, int version);
void enterSafeMode();
boolean isSafeMode();
void systemReady();
boolean hasSystemUidErrors();
void performFstrimIfNeeded();
void updatePackagesIfNeeded();
oneway void notifyPackageUse(String packageName, int reason);
oneway void notifyDexLoad(String loadingPackageName, in List<String> classLoadersNames,in List<String> classPaths, String loaderIsa);
oneway void registerDexModule(in String packageName, in String dexModulePath,in boolean isSharedModule, IDexModuleRegisterCallback callback);
boolean performDexOptMode(String packageName, boolean checkProfiles,String targetCompilerFilter, boolean force, boolean bootComplete, String splitName);
boolean performDexOptSecondary(String packageName,String targetCompilerFilter, boolean force);
void dumpProfiles(String packageName);
void forceDexOpt(String packageName);
boolean runBackgroundDexoptJob(in List<String> packageNames);
void reconcileSecondaryDexFiles(String packageName);
PackageCleanItem nextPackageToClean(in PackageCleanItem lastPackage);
int getMoveStatus(int moveId);
void registerMoveCallback(in IPackageMoveObserver callback);
void unregisterMoveCallback(in IPackageMoveObserver callback);
int movePackage(in String packageName, in String volumeUuid);
int movePrimaryStorage(in String volumeUuid);
boolean addPermissionAsync(in PermissionInfo info);
boolean setInstallLocation(int loc);
int getInstallLocation();
int installExistingPackageAsUser(String packageName, int userId, int installFlags,int installReason);
void verifyPendingInstall(int id, int verificationCode);
void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay);
void verifyIntentFilter(int id, int verificationCode, in List<String> failedDomains);
int getIntentVerificationStatus(String packageName, int userId);
boolean updateIntentVerificationStatus(String packageName, int status, int userId);
ParceledListSlice getIntentFilterVerifications(String packageName);
ParceledListSlice getAllIntentFilters(String packageName);
boolean setDefaultBrowserPackageName(String packageName, int userId);
String getDefaultBrowserPackageName(int userId);
VerifierDeviceIdentity getVerifierDeviceIdentity();
boolean isFirstBoot();
boolean isOnlyCoreApps();
boolean isUpgrade();
void setPermissionEnforced(String permission, boolean enforced);
boolean isPermissionEnforced(String permission);
boolean isStorageLow();
boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden);
boolean setSystemAppInstallState(String packageName, boolean installed, int userId);
IPackageInstaller getPackageInstaller();
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
boolean getBlockUninstallForUser(String packageName, int userId);
KeySet getKeySetByAlias(String packageName, String alias);
KeySet getSigningKeySet(String packageName);
boolean isPackageSignedByKeySet(String packageName, in KeySet ks);
boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks);
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
void grantDefaultPermissionsToEnabledTelephonyDataServices(in String[] packageNames, int userId);
void revokeDefaultPermissionsFromDisabledTelephonyDataServices(in String[] packageNames, int userId);
void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
String getPermissionControllerPackageName();
ParceledListSlice getInstantApps(int userId);
byte[] getInstantAppCookie(String packageName, int userId);
boolean setInstantAppCookie(String packageName, in byte[] cookie, int userId);
Bitmap getInstantAppIcon(String packageName, int userId);
boolean isInstantApp(String packageName, int userId);
boolean setRequiredForSystemUser(String packageName, boolean systemUserApp);
void setUpdateAvailable(String packageName, boolean updateAvaialble);
String getServicesSystemSharedLibraryPackageName();
String getSharedSystemSharedLibraryPackageName();
ChangedPackages getChangedPackages(int sequenceNumber, int userId);
boolean isPackageDeviceAdminOnAnyUser(String packageName);
int getInstallReason(String packageName, int userId);
ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId);
boolean canRequestPackageInstalls(String packageName, int userId);
void deletePreloadsFileCache();
ComponentName getInstantAppResolverComponent();
ComponentName getInstantAppResolverSettingsComponent();
ComponentName getInstantAppInstallerComponent();
String getInstantAppAndroidId(String packageName, int userId);
IArtManager getArtManager();
void setHarmfulAppWarning(String packageName, CharSequence warning, int userId);
CharSequence getHarmfulAppWarning(String packageName, int userId);
boolean hasSigningCertificate(String packageName, in byte[] signingCertificate, int flags);
boolean hasUidSigningCertificate(int uid, in byte[] signingCertificate, int flags);
String getSystemTextClassifierPackageName();
boolean isPackageStateProtected(String packageName, int userId);
END
)
Edit:
Using the highlight command, I can get syntax highlighting working to some degree, but it doesn't recognize a lot of the data types. For example it works for boolean, int and byte, but it doesn't work for String, ComponentName, IOnPermissionsChangeListener, etc..
echo "$CODE" | highlight --out-format=xterm256 --syntax=java
It seems like a more reliable way could be to use some sort of regex replacements to add colors line by line.
E.g.
method name: ends before the ( character starts at first space
found before the (.
parameter names: a word directly preceding a
, or ) (there can be additional spaces between the word and the
, or ).
data types: all words (respectively excluding the last
one) between (( and ,) or (, and ,) or (, and ), or
(beginning of line and (
But I can't think of a reasonable way to implement this in Bash.
I'm asking for a solution to a problem
Steps:
Write a parser for the syntax you want to parse. Preferably in real programming language, like python or C++. Tokenize input and detect token types (function return type, function identifier, parameters types, parameter identifiers, etc.).
Apply specific colors to specific tokens types.
Output.
I can't think of a reasonable way to implement this in Bash.
I can't think either, I believe because there are none reasonable ways to do it in bash. Bash is a shell, it's not a full easy to use programming language, it's not fast, it's a shell meant primarily to run other programs. Consider a different language. You could aim for awk, but I would go with python.
For simple cases you may write it in regex ex. in sed or awk (still - not bash) and tokenize input with some regexes, apply colors and output, but I do not believe you'll be able to handle ex. function pointers in C++.
Sample tokenizer written in sed, just for funzies:
echo 'void checkPackageStartable(String packageName, int userId);' |
sed '
s/^ *\([^(,)]\+\) \+\([^ (,)]\+\)\([(,)]\)\(.*\)/\4\n{FUNCRET}\1\n{FUNCNAME}\2\n{SEP}\3\n/;
h;
:a; {
/^ *\([^(,)]\+\) \+\([^ (,)]\+\)\([(,)]\)\([^\n]*\)\n\(.*\)$/{
s//\4\n\5{PARTYPE}\1\n{PARNAME}\2\n{SEP}\3\n/
b a
}
}
s/^;\(.*\)/\1{END};/
'
outputs:
{FUNCRET}void
{FUNCNAME}checkPackageStartable
{SEP}(
{PARTYPE}String
{PARNAME}packageName
{SEP},
{PARTYPE}int
{PARNAME}userId
{SEP})
{END};
You can modify such sed script to apply colors from some variables instead of marks and change newlines to spaces on output for your requested output.
When I tried to serialize a generic list of objects, I get some data loss, with any of the variables that are used by the derived classes. I used to have those variables in the derived class, but since the base class was getting serialized I assumed the derived variables would get ignored.
The Code:
[XmlInclude(typeof(AchievementStock))]
[XmlInclude(typeof(AchievementCash))]
[XmlInclude(typeof(AchievementStockSpecify))]
public abstract class Achievement : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected string _title;
protected string _description;
protected int _cashValue;
protected bool _completed;
//Cash
protected int _amountCash;
protected bool _greater;
//Stocks
protected int _amountStocks;
//StockSpecify
protected string _stockName;
protected int _amount;
public abstract void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager);
public Achievement()
{
}
public Achievement(string title, string description, int cashValue, bool completed)
{
Title = title;
Description = description;
_cashValue = cashValue;
_completed = completed;
}
public void PropertyChangedEvent(string assetName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(assetName));
}
}
}
public class AchievementCash : Achievement
{
public AchievementCash(string title, string description, int cashValue, bool completed, int amountCash, bool greater)
: base(title, description, cashValue, completed)
{
_amountCash = amountCash;
_greater = greater;
}
public AchievementCash()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
public class AchievementStock : Achievement
{
public AchievementStock(string title, string description, int cashValue, bool completed, int amountStocks)
: base(title, description, cashValue, completed)
{
_amountStocks = amountStocks;
}
public AchievementStock()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
public class AchievementStockSpecify : Achievement
{
public AchievementStockSpecify(string title, string description, int cashValue, bool completed, string stockName, int amount)
: base(title, description, cashValue, completed)
{
_stockName = stockName;
_amount = amount;
}
public AchievementStockSpecify()
{
}
public override void CheckAchievement(AssetManager assetManager, AchievementManager achievementManager)
{
}
}
The variables that become default value are:
//Cash
protected int _amountCash;
protected bool _greater;
//Stocks
protected int _amountStocks;
//StockSpecify
protected string _stockName;
protected int _amount;
Anyone have any ideas on why this is occurring?
You must have public fields rather than protected fields as only public properties and fields can be serialized by XMLSerializer.