HIDL কোড স্টাইল Android ফ্রেমওয়ার্কে C++ কোডের মতো, এতে ৪-স্পেস ইনডেন্ট ও মিক্সড-কেস ফাইলনেম থাকে। প্যাকেজ ডিক্লারেশন, ইমপোর্ট ও ডকস্ট্রিং Java-এর মতোই, তবে সামান্য পরিবর্তন করা হয়েছে।
IFoo.hal ও types.hal-এর জন্য নিম্নলিখিত উদাহরণগুলি
HIDL কোড স্টাইল ব্যাখ্যা করে এবং প্রতিটি স্টাইলের বিবরণের জন্য ডাইরেক্ট লিঙ্ক প্রদান করে
(IFooClientCallback.hal, IBar.hal ও
IBaz.hal বাদ দেওয়া হয়েছে)।
hardware/interfaces/foo/1.0/IFoo.hal |
|---|
/* * (License Notice) */ package android.hardware.foo@1.0; import android.hardware.bar@1.0::IBar; import IBaz; import IFooClientCallback; /** * IFoo is an interface that… */ interface IFoo { /** * This is a multiline docstring. * * @return result 0 if successful, nonzero otherwise. */ foo() generates (FooStatus result); /** * Restart controller by power cycle. * * @param bar callback interface that… * @return result 0 if successful, nonzero otherwise. */ powerCycle(IBar bar) generates (FooStatus result); /** Single line docstring. */ baz(); /** * The bar function. * * @param clientCallback callback after function is called * @param baz related baz object * @param data input data blob */ bar(IFooClientCallback clientCallback, IBaz baz, FooData data); }; |
hardware/interfaces/foo/1.0/types.hal |
|---|
/* * (License Notice) */ package android.hardware.foo@1.0; /** Replied status. */ enum Status : int32_t { OK, /* invalid arguments */ ERR_ARG, /* note, no transport related errors */ ERR_UNKNOWN = -1, }; struct ArgData { int32_t[20] someArray; vec<uint8_t> data; }; |
নামকরণ সংক্রান্ত কনভেনশন
ফাংশনের নাম, ভেরিয়েবলের নাম এবং ফাইলের নাম বর্ণনামূলক হতে হবে;
অতিরিক্ত সংক্ষিপ্তকরণ এড়িয়ে চলুন। সংক্ষিপ্ত রূপকে শব্দ হিসেবে বিবেচনা করুন (যেমন, INFC-এর পরিবর্তে INfc ব্যবহার করুন)।
ডিরেক্টরি স্ট্রাকচার ও ফাইলের নামকরণ
ডিরেক্টরি স্ট্রাকচার নিম্নলিখিতভাবে দেখানো উচিত:
ROOT-DIRECTORYMODULESUBMODULE(ঐচ্ছিক, একাধিক লেভেল থাকতে পারে )VERSIONAndroid.mkIINTERFACE_1.halIINTERFACE_2.hal…IINTERFACE_N.haltypes.hal(ঐচ্ছিক)
যেখানে:
ROOT-DIRECTORYহল:- কোর HIDL প্যাকেজের জন্য
hardware/interfaces। vendor/VENDOR/interfacesভেন্ডর প্যাকেজের জন্য, যেখানেVENDORবলতে SoC ভেন্ডর বা OEM/ODM-কে বোঝানো হয়েছে।
- কোর HIDL প্যাকেজের জন্য
MODULEহল একটি ছোট হাতের শব্দ যা সাবসিস্টেমের বর্ণনা করে (যেমন,nfc)। একাধিক শব্দের প্রয়োজন হলে, নেস্ট করাSUBMODULEব্যবহার করুন। নেস্টিংয়ের একাধিক লেভেল থাকতে পারে।VERSION-এর ভার্সন ভার্সন-এ বর্ণিত ভার্সনের (major.minor) সাথে হুবহু মিলতে হবে।IINTERFACE_Xহল ইন্টারফেসের নাম যার সাথেUpperCamelCase/PascalCase(যেমন,INfc) ইন্টারফেসের নাম বিভাগে বর্ণনা করা হয়েছে।
উদাহরণ:
hardware/interfacesnfc1.0Android.mkINfc.halINfcClientCallback.haltypes.hal
মনে রাখবেন: সব ফাইলের ক্ষেত্রে নন-এক্সিকিউটেবল অনুমতি (Git-এ) থাকতে হবে।
প্যাকেজের নাম
প্যাকেজের নাম অবশ্যই নিম্নলিখিত সম্পূর্ণরূপে উপযুক্ত নাম
(FQN) ফর্ম্যাট (PACKAGE-NAME হিসেবে উল্লেখ করা হয়েছে) ব্যবহার করতে হবে:
PACKAGE.MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION
যেখানে:
PACKAGEহল সেই প্যাকেজ যাROOT-DIRECTORY-এর সাথে ম্যাপ করে। বিশেষ করে,PACKAGEহল:- কোর HIDL প্যাকেজের জন্য
android.hardware(hardware/interfaces-এ ম্যাপিং)। vendor.VENDOR.hardwareভেন্ডর প্যাকেজের জন্য, যেখানেVENDORবলতে SoC ভেন্ডর বা OEM/ODM (ম্যাপিং থেকেvendor/VENDOR/interfaces) বোঝায়।
- কোর HIDL প্যাকেজের জন্য
MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSIONডিরেক্টরি স্ট্রাকচার-এ বর্ণিত স্ট্রাকচারে ঠিক একই ফোল্ডারের নাম।- প্যাকেজের নাম ছোট হাতের অক্ষরে লিখতে হবে। সেগুলি একাধিক শব্দের হলে, শব্দগুলিকে
সাবমডিউল হিসেবে ব্যবহার করতে হবে অথবা
snake_case-এ লিখতে হবে। - কোনও স্পেস ব্যবহার করা যাবে না।
প্যাকেজ ডিক্লারেশনে সবসময় FQN ব্যবহার করা হয়।
বিভিন্ন ভার্সন
ভার্সন নিম্নলিখিত ফর্ম্যাটে থাকতে হবে:
MAJOR.MINOR
MAJOR ও MINOR, দুটি ভার্সনই একটি করে পূর্ণসংখ্যা হতে হবে। HIDL সিমেটিক ভার্সনিং নিয়ম ব্যবহার করে।
ইমপোর্ট
ইমপোর্টের তিনটি ফর্ম্যাটের মধ্যে একটি থাকে:
- সম্পূর্ণ প্যাকেজ ইমপোর্ট করা:
import PACKAGE-NAME; - আংশিক ইমপোর্ট:
import PACKAGE-NAME::UDT;(অথবা, ইমপোর্ট করা টাইপ একই প্যাকেজে থাকলে,import UDT; - শুধুমাত্র টাইপ ইমপোর্ট করা:
import PACKAGE-NAME::types;
PACKAGE-NAME, প্যাকেজের নাম-এ
উল্লেখ করা ফর্ম্যাট অনুসরণ করে। বর্তমান প্যাকেজের
types.hal (যদি থাকে) অটোমেটিক ইমপোর্ট করা হয় (এটি
আলাদা করে ইমপোর্ট করবেন না)।
সম্পূর্ণরূপে উপযুক্ত নাম (FQN)
শুধুমাত্র প্রয়োজন হলে ব্যবহারকারীর দ্বারা নির্ধারিত ধরনের ইম্পোর্টের জন্য সম্পূর্ণরূপে উপযুক্ত নাম ব্যবহার করুন।
ইমপোর্ট টাইপ একই প্যাকেজে থাকলে PACKAGE-NAME বাদ দিন। FQN-এ কোনও স্পেস থাকা চলবে না। সম্পূর্ণভাবে উপযুক্ত নামের উদাহরণ:
android.hardware.nfc@1.0::INfcClientCallback
android.hardware.nfc@1.0-এর অধীনে অন্য একটি ফাইলে, INfcClientCallback হিসেবে
উপরের ইন্টারফেস দেখুন। অন্যথায়, শুধুমাত্র
সম্পূর্ণ কোয়ালিফায়েড নাম ব্যবহার করুন।
ইমপোর্ট গ্রুপ ও অর্ডার করা
প্যাকেজ ঘোষণার পরে (ইমপোর্ট করার আগে) একটি খালি লাইন ব্যবহার করুন। প্রতিটি ইমপোর্ট এক একটি লাইন জুড়ে থাকতে হবে এবং ইন্ডেন্ট করা যাবে না। নিম্নলিখিত ক্রম অনুসারে গ্রুপ ইমপোর্ট করুন:
- অন্যান্য
android.hardwareপ্যাকেজ (সম্পূর্ণ কোয়ালিফায়েড নাম ব্যবহার করুন)। - অন্যান্য
vendor.VENDORপ্যাকেজ (সম্পূর্ণ কোয়ালিফায়েড নাম ব্যবহার করুন)।- প্রতিটি ভেন্ডরকে একটি গ্রুপ হতে হবে।
- বর্ণানুক্রমিকভাবে ভেন্ডরদের সাজান।
- একই প্যাকেজের অন্যান্য ইন্টারফেস থেকে ইমপোর্ট (সহজ নাম ব্যবহার করুন)।
দুটি গ্রুপের মধ্যে একটি ফাঁকা লাইন ব্যবহার করুন। প্রতিটি গ্রুপের মধ্যে, ইমপোর্টগুলি বর্ণানুক্রমিকভাবে সাজান। উদাহরণ:
import android.hardware.nfc@1.0::INfc; import android.hardware.nfc@1.0::INfcClientCallback; /* Importing the whole module. */ import vendor.barvendor.bar@3.1; import vendor.foovendor.foo@2.2::IFooBar; import vendor.foovendor.foo@2.2::IFooFoo; import IBar; import IFoo;
ইন্টারফেসের নাম
ইন্টারফেসের নাম অবশ্যই I দিয়ে শুরু হতে হবে, তারপরে
UpperCamelCase/PascalCase নাম লিখতে হবে। IFoo.hal ফাইলে
IFoo নামের একটি ইন্টারফেস অবশ্যই সংজ্ঞায়িত করতে হবে। এই ফাইলে
শুধুমাত্র IFoo ইন্টারফেসের জন্য সংজ্ঞা থাকতে পারে (ইন্টারফেস
INAME INAME.hal-এ থাকতে হবে)।
অপেক্ষক
ফাংশনের নাম, আর্গুমেন্ট এবং রিটার্ন ভেরিয়েবলের নামের জন্য
lowerCamelCase ব্যবহার করুন। উদাহরণ:
open(INfcClientCallback clientCallback) generates (int32_t retVal); oneway pingAlive(IFooCallback cb);
Struct ও ইউনিয়ন ফিল্ডের নাম
স্ট্রাক্ট বা ইউনিয়ন ফিল্ডের নামের জন্য, lowerCamelCase ব্যবহার করুন। উদাহরণ:
struct FooReply {
vec<uint8_t> replyData;
}নামের ধরন
টাইপ নামের মধ্যে স্ট্রাকচার বা ইউনিয়নের সংজ্ঞা, এনুম টাইপের সংজ্ঞা এবং
typedefs পড়ে। এইসব নামের জন্য, UpperCamelCase/PascalCase ব্যবহার করুন। উদাহরণ:
enum NfcStatus : int32_t { /*...*/ }; struct NfcData { /*...*/ };
এনাম ভ্যালু
এনাম ভ্যালু UPPER_CASE_WITH_UNDERSCORES হতে হবে। ফাংশন আর্গুমেন্ট হিসেবে enum ভ্যালু পাস করানোর সময় এবং ফাংশন রিটার্ন হিসেবে সেগুলি রিটার্ন করার সময়, আসল enum টাইপ (আন্ডারলায়িং ইন্টিজার টাইপ নয়) ব্যবহার করুন। উদাহরণ:
enum NfcStatus : int32_t { HAL_NFC_STATUS_OK = 0, HAL_NFC_STATUS_FAILED = 1, HAL_NFC_STATUS_ERR_TRANSPORT = 2, HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 3, HAL_NFC_STATUS_REFUSED = 4 };
মনে রাখবেন: কোনও এনুম টাইপের অন্তর্নিহিত ধরনটি কোলন চিহ্নের পরে স্পষ্টভাবে ঘোষণা করা হয়। যেহেতু এটি কম্পাইলার নির্ভর নয়, তাই আসল এনাম টাইপ ব্যবহার করলে তা আরও স্পষ্ট হয়।
এনাম ভ্যালুর সম্পূর্ণ উপযুক্ত নামের ক্ষেত্রে, এনামের ধরন ও এনাম ভ্যালুর নামের মধ্যে একটি কোলন ব্যবহার করা হয়:
PACKAGE-NAME::UDT[.UDT[.UDT[…]]:ENUM_VALUE_NAME
সম্পূর্ণরূপে উপযুক্ত নামের মধ্যে কোনও স্পেস থাকলে চলবে না। সম্পূর্ণ কোয়ালিফায়েড নাম শুধুমাত্র প্রয়োজন হলেই ব্যবহার করুন এবং অপ্রয়োজনীয় অংশ বাদ দিন। উদাহরণ:
android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK
কমেন্ট
এক লাইনের কমেন্টের জন্য, //, /* */ ও /** */
ঠিক আছে।
// This is a single line comment /* This is also single line comment */ /** This is documentation comment */
-
কমেন্টের জন্য
/* */ব্যবহার করুন। HIDL কমেন্টের জন্য//সাপোর্ট করলেও, সেগুলি ব্যবহার করতে নিরুৎসাহিত করা হয় কারণ সেগুলি জেনারেট করা আউটপুটে দেখা যায় না। - জেনারেট করা ডকুমেন্টেশনের জন্য
/** */ব্যবহার করুন। এগুলি শুধুমাত্র ধরন, পদ্ধতি, ফিল্ড এবং এনাম ভ্যালু ডিক্লারেশনের ক্ষেত্রে প্রয়োগ করা যেতে পারে। উদাহরণ:/** Replied status */ enum TeleportStatus { /** Object entirely teleported. */ OK = 0, /** Methods return this if teleportation is not completed. */ ERROR_TELEPORT = 1, /** * Teleportation could not be completed due to an object * obstructing the path. */ ERROR_OBJECT = 2, ... }
- আলাদা লাইনে
/**দিয়ে মাল্টি-লাইন কমেন্ট শুরু করুন। প্রতিটি লাইনের শুরুতে*ব্যবহার করুন। অ্যাস্টেরিস্ক অ্যালাইন করে, আলাদা লাইনে*/দিয়ে কমেন্ট শেষ করো। উদাহরণ:/** * My multi-line * comment */
- লাইসেন্সিং বিজ্ঞপ্তি এবং চেঞ্জলগ
/*(একটি অ্যাস্টেরিস্ক) দিয়ে নতুন লাইন শুরু করতে হবে, প্রতিটি লাইনের শুরুতে*ব্যবহার করতে হবে এবং শেষ লাইনে*/রাখতে হবে (অ্যাস্টেরিস্কগুলি সারিবদ্ধ হতে হবে)। উদাহরণ:/* * Copyright (C) 2017 The Android Open Source Project * ... */ /* * Changelog: * ... */
ফাইল কমেন্ট
প্রতিটি ফাইল উপযুক্ত লাইসেন্স বিজ্ঞপ্তি দিয়ে শুরু করুন। কোর HAL-এর জন্য, এটি
development/docs/copyright-templates/c.txt-এ AOSP Apache লাইসেন্স
হওয়া উচিত।
বছর আপডেট করতে এবং উপরে ব্যাখ্যা করা /* */ স্টাইলের মাল্টি-লাইন কমেন্ট
ব্যবহার করতে ভুলবেন না।
আপনি চাইলে লাইসেন্স বিজ্ঞপ্তির পরে একটি ফাঁকা লাইন রাখতে পারেন, তারপরে
পরিবর্তনের লগ/ভার্সনিং সংক্রান্ত তথ্য দিতে পারেন। উপরে যেমন ব্যাখ্যা করা হয়েছে, সেই অনুযায়ী /* */ স্টাইলের
মাল্টি-লাইন কমেন্ট ব্যবহার করুন, চেঞ্জলগের পরে খালি লাইন রাখুন,
তারপরে প্যাকেজ ডিক্লারেশন লিখুন।
করণীয় কমেন্ট
TODO-তে সব বড় হাতের অক্ষরে TODO স্ট্রিং এবং তারপরে কোলন
থাকতে হবে। উদাহরণ:
// TODO: remove this code before foo is checked in.
TODO কমেন্ট শুধুমাত্র ডেভেলপমেন্টের সময় করা যায়; প্রকাশিত ইন্টারফেসে এগুলি থাকলে চলবে না।
ইন্টারফেস ও ফাংশন কমেন্ট (ডকস্ট্রিং)
একাধিক লাইন ও একটি লাইনের ডকস্ট্রিংয়ের জন্য /** */ ব্যবহার করুন। ডকস্ট্রিংয়ের জন্য
// ব্যবহার করবেন না।
ইন্টারফেসের জন্য ডকস্ট্রিংয়ে ইন্টারফেসের সাধারণ মেকানিজম, ডিজাইন র্যাশনাল, উদ্দেশ্য ইত্যাদি বর্ণনা করা উচিত। ফাংশনের জন্য ডকস্ট্রিংয়ে ফাংশন নির্দিষ্ট হতে হবে (প্যাকেজ-লেভেল ডকুমেন্টেশন প্যাকেজ ডিরেক্টরির README ফাইলে থাকে)।
/** * IFooController is the controller for foos. */ interface IFooController { /** * Opens the controller. * * @return status HAL_FOO_OK if successful. */ open() generates (FooStatus status); /** Close the controller. */ close(); };
আপনাকে অবশ্যই প্রতিটি
প্যারামিটার/রিটার্ন ভ্যালুর জন্য @params এবং @returns যোগ করতে হবে:
- প্রতিটি প্যারামিটারের জন্য
@paramযোগ করতে হবে। এটির পরে প্যারামিটারের নাম ও তারপরে ডকস্ট্রিং লিখতে হবে। - প্রতিটি রিটার্ন ভ্যালুর জন্য
@returnযোগ করতে হবে। এর পরে রিটার্ন ভ্যালুর নাম ও তারপরে ডকস্ট্রিং লিখতে হবে।
উদাহরণ:
/** * Explain what foo does. * * @param arg1 explain what arg1 is * @param arg2 explain what arg2 is * @return ret1 explain what ret1 is * @return ret2 explain what ret2 is */ foo(T arg1, T arg2) generates (S ret1, S ret2);
ফর্ম্যাটিং সংক্রান্ত নিয়ম
সাধারণ ফর্ম্যাটিং সংক্রান্ত নিয়মের মধ্যে এগুলি পড়ে:
- লাইনের দৈর্ঘ্য। টেক্সটের প্রতিটি লাইন সর্বাধিক ১০০ কলাম দীর্ঘ হতে হবে।
- হোয়াইটস্পেস। লাইনের শেষে কোনও হোয়াইটস্পেস নেই; খালি লাইনে হোয়াইটস্পেস থাকলে চলবে না।
- স্পেস বনাম ট্যাব। শুধুমাত্র স্পেস ব্যবহার করুন।
- ইন্ডেন্ট সাইজ। ব্লকের জন্য ৪টি স্পেস এবং লাইন র্যাপের জন্য ৮টি স্পেস ব্যবহার করুন
- ব্রেসিং। অ্যানোটেশন
ভ্যালু ছাড়া, খোলা বন্ধনী আগের
কোডের মতো একই লাইনে বসে, কিন্তু বন্ধ বন্ধনী ও তার পরের সেমিকোলন
পুরো লাইন জুড়ে বসে। উদাহরণ:
interface INfc { close(); };
প্যাকেজ সংক্রান্ত ঘোষণা
লাইসেন্স বিজ্ঞপ্তির পরে ফাইলের একদম উপরে প্যাকেজ ঘোষণা করতে হবে, পুরো লাইন জুড়ে থাকতে হবে এবং ইন্ডেন্ট করা যাবে না। প্যাকেজগুলি নিম্নলিখিত ফর্ম্যাট ব্যবহার করে ঘোষণা করা হয় (নাম ফর্ম্যাটিংয়ের জন্য, প্যাকেজের নাম দেখুন):
package PACKAGE-NAME;
উদাহরণ:
package android.hardware.nfc@1.0;
ফাংশন ঘোষণা
ফাংশনের নাম, প্যারামিটার, generates এবং রিটার্ন ভ্যালু একই লাইনে
থাকলে ভাল হয়, যদি সেগুলি জায়গা করে নিতে পারে। উদাহরণ:
interface IFoo {
/** ... */
easyMethod(int32_t data) generates (int32_t result);
};সেগুলি একই লাইনে না ধরলে, একই ইন্ডেন্ট লেভেলে প্যারামিটার ও রিটার্ন
ভ্যালু রাখার চেষ্টা করুন এবং generate আলাদা করে দেখান যাতে
পাঠক প্যারামিটার ও রিটার্ন ভ্যালু দ্রুত দেখতে পান। উদাহরণ:
interface IFoo {
suchALongMethodThatCannotFitInOneLine(int32_t theFirstVeryLongParameter,
int32_t anotherVeryLongParameter);
anEvenLongerMethodThatCannotFitInOneLine(int32_t theFirstLongParameter,
int32_t anotherVeryLongParameter)
generates (int32_t theFirstReturnValue,
int32_t anotherReturnValue);
superSuperSuperSuperSuperSuperSuperLongMethodThatYouWillHateToType(
int32_t theFirstVeryLongParameter, // 8 spaces
int32_t anotherVeryLongParameter
) generates (
int32_t theFirstReturnValue,
int32_t anotherReturnValue
);
/* method name is even shorter than 'generates' */
foobar(AReallyReallyLongType aReallyReallyLongParameter,
AReallyReallyLongType anotherReallyReallyLongParameter)
generates (ASuperLongType aSuperLongReturnValue, // 4 spaces
ASuperLongType anotherSuperLongReturnValue);
}অতিরিক্ত বিবরণ:
- ফাংশনের নামের সাথে একই লাইনে সবসময় ওপেন প্যারেনথেসিস থাকে।
- ফাংশনের নাম ও প্রথম বন্ধনীর মধ্যে কোনও স্পেস নেই।
- বন্ধনী ও প্যারামিটারের মধ্যে কোনও স্পেস থাকবে না তবে তাদের মধ্যে লাইন ফিড থাকলে স্পেস থাকতে পারে।
generatesযদি আগের বন্ধনী শেষ হওয়ার লাইনেই থাকে, তাহলে তার আগে একটি স্পেস দিন। পরের ওপেন প্যারেনথিসিসgeneratesএকই লাইনে থাকলে একটি স্পেস দিয়ে শুরু করুন।- সব প্যারামিটার ও রিটার্ন ভ্যালু (সম্ভব হলে) অ্যালাইন করুন।
- ডিফল্ট ইন্ডেন্টেশন হল ৪টি স্পেস।
- মোড়ানো প্যারামিটারগুলি আগের লাইনের প্রথম প্যারামিটারের সাথে অ্যালাইন করা হয়, অন্যথায় সেগুলিতে ৮-স্পেস ইন্ডেন্ট থাকে।
টিকা
অ্যানোটেশনের জন্য নিম্নলিখিত ফর্ম্যাট ব্যবহার করুন:
@annotate(keyword = value, keyword = {value, value, value})
অ্যানোটেশন বর্ণানুক্রমিকভাবে সাজান এবং সমান চিহ্নের চারপাশে স্পেস ব্যবহার করুন। উদাহরণ:
@callflow(key = value) @entry @exit
নিশ্চিত করুন যে কোনও অ্যানোটেশন পুরো লাইন জুড়ে আছে। উদাহরণ:
/* Good */ @entry @exit /* Bad */ @entry @exit
অ্যানোটেশন একই লাইনে ফিট না হলে, ৮টি স্পেস দিয়ে ইন্ডেন্ট করুন। উদাহরণ:
@annotate( keyword = value, keyword = { value, value }, keyword = value)
পুরো ভ্যালু অ্যারে একই লাইনে না ধরলে, ওপেন ব্রেস { এবং অ্যারের মধ্যে প্রতিটি কমার পরে লাইন ব্রেক দিন। শেষ মানের ঠিক পরেই বন্ধনী
চিহ্ন দিন। একটি মাত্র ভ্যালু থাকলে ব্রেসেস
দেবেন না।
সম্পূর্ণ ভ্যালু অ্যারে একই লাইনে ফিট করলে, ওপেনিং ব্রেসের পরে এবং ক্লোজিং ব্রেসের আগে স্পেস ব্যবহার করবেন না এবং প্রতিটি কমার পরে একটি স্পেস ব্যবহার করুন। উদাহরণ:
/* Good */ @callflow(key = {"val", "val"}) /* Bad */ @callflow(key = { "val","val" })
অ্যানোটেশন ও ফাংশন ডিক্লারেশনের মধ্যে কোনও খালি লাইন থাকা চলবে না। উদাহরণ:
/* Good */ @entry foo(); /* Bad */ @entry foo();
Enum ডিক্লারেশন
এনাম ঘোষণা করার জন্য নিম্নলিখিত নিয়ম ব্যবহার করুন:
- এনাম ঘোষণা অন্য প্যাকেজের সাথে শেয়ার করা হলে, ইন্টারফেসের মধ্যে এম্বেড না করে ঘোষণাগুলি
types.hal-এর মধ্যে রাখুন। - কোলন চিহ্নের আগে ও পরে স্পেস এবং ওপেন ব্রেসের আগে আন্ডারলাইন করা ধরনের পরে স্পেস দিন।
- শেষ এনুম ভ্যালুতে অতিরিক্ত কমা নাও থাকতে পারে।
স্ট্রাক্ট ঘোষণা
স্ট্রাক্ট ডিক্লারেশনের জন্য নিম্নলিখিত নিয়মগুলি ব্যবহার করুন:
- স্ট্রাক্ট ডিক্লারেশন অন্য প্যাকেজের সাথে শেয়ার করা হলে, ইন্টারফেসের মধ্যে এম্বেড করার পরিবর্তে
types.hal-এ ডিক্লারেশন রাখুন। - ওপেন ব্রেসের আগে struct টাইপের নামের পরে একটি স্পেস ব্যবহার করুন।
- ফিল্ডের নামগুলি সারিবদ্ধ করুন (ঐচ্ছিক)। উদাহরণ:
struct MyStruct { vec<uint8_t> data; int32_t someInt; }
অ্যারে ঘোষণা
নিম্নলিখিতগুলির মধ্যে স্পেস দেবেন না:
- এলিমেন্টের ধরন ও প্রথম বন্ধনী।
- শুরুর থার্ড ব্র্যাকেট ও অ্যারের সাইজ।
- অ্যারের সাইজ ও ক্লোজিং স্কোয়ার ব্র্যাকেট।
- ক্লোজ স্কোয়ার ব্র্যাকেট এবং পরবর্তী ওপেন স্কোয়ার ব্র্যাকেট, যদি একাধিক ডাইমেনশন থাকে।
উদাহরণ:
/* Good */ int32_t[5] array; /* Good */ int32_t[5][6] multiDimArray; /* Bad */ int32_t [ 5 ] [ 6 ] array;
ভেক্টর
নিম্নলিখিতগুলির মধ্যে কোনও স্পেস দেবেন না:
vecএবং ওপেন অ্যাঙ্গেল ব্র্যাকেট।- ওপেন অ্যাঙ্গেল ব্র্যাকেট এবং এলিমেন্টের ধরন (ব্যতিক্রম: এলিমেন্টের ধরনও একটি
vec)। - এলিমেন্টের ধরন ও ক্লোজিং অ্যাঙ্গেল ব্র্যাকেট (ব্যতিক্রম: এলিমেন্টের ধরন হল a
vec)।
উদাহরণ:
/* Good */ vec<int32_t> array; /* Good */ vec<vec<int32_t>> array; /* Good */ vec< vec<int32_t> > array; /* Bad */ vec < int32_t > array; /* Bad */ vec < vec < int32_t > > array;