├── README.MD ├── form.sh ├── installer.sh └── makefile.sh /README.MD: -------------------------------------------------------------------------------- 1 | # C++ Class Generator Script 2 | 3 | This script generates C++ class files with getters, setters, and other necessary functions. 4 | 5 | ## Install 6 | 7 | ``` bash 8 | bash -c "$(curl -fsSL https://raw.github.com/LuckyIntegral/Cpp-Class-Creator/main/installer.sh)" 9 | ``` 10 | 11 | ## Prerequisites 12 | 13 | - Ensure that you have the required utilities installed (zsh, awk, sed, tr). 14 | 15 | ## Usage 16 | 17 | ```zsh 18 | form [attributeType, attributeName] ... 19 | ``` 20 | ### Options 21 | 22 | **ClassName**: Name of the C++ class. \ 23 | **attributeType**: Type of class attribute (e.g., int, std::stringm unsigned long int). \ 24 | **attributeName**: Name of class attribute. 25 | 26 | ## Example 27 | 28 | ```zsh 29 | form MyClass int age std::string name 'unsigned long int' bankAccount 30 | ``` 31 | 32 | ## Generated Files 33 | 34 | - MyClass.cpp: Contains the implementation of the MyClass class that follows next rules: 35 | - Default constructor 36 | - \ All args constructor 37 | - Copy constructor 38 | - Destructor 39 | - Copy assignment operator '=' 40 | - \ Getters and setters for private atributes 41 | - Overload of << operator for your class 42 | - MyClass.hpp: Contains the class declaration that has all the necessary stuff for comfort usage 43 | - Declaration of destructor, constructors and overload operators 44 | - Declaration of all the getters and setters for private atributes 45 | - Macroses with default values for the atributes 46 | 47 | ## Contributions 48 | 49 | __Contributions are welcome! If you find any issues or havesuggestions for improvements, feel free to submit a pull request.__ 50 | -------------------------------------------------------------------------------- /form.sh: -------------------------------------------------------------------------------- 1 | 2 | put_header() { 3 | local login_length=${#USER} 4 | local file_length=${#1} 5 | local basename="$(basename $1)" 6 | local login_spaces="" 7 | local file_spaces="" 8 | local formatted_date_time=$(date '+%Y/%m/%d %H:%M:%S') 9 | 10 | for (( i = 0; i < 8 - login_length; ++i )); do 11 | login_spaces+=" " 12 | done 13 | 14 | for (( i = 0; i < 51 - file_length; ++i )); do 15 | file_spaces+=" " 16 | done 17 | 18 | cat < "$1" 19 | /* ************************************************************************** */ 20 | /* */ 21 | /* ::: :::::::: */ 22 | /* $basename$file_spaces:+: :+: :+: */ 23 | /* +:+ +:+ +:+ */ 24 | /* By: $USER <$USER@student.42.fr> $login_spaces$login_spaces+#+ +:+ +#+ */ 25 | /* +#+#+#+#+#+ +#+ */ 26 | /* Created: $formatted_date_time by $USER $login_spaces#+# #+# */ 27 | /* Updated: $formatted_date_time by $USER $login_spaces### ########.fr */ 28 | /* */ 29 | /* ************************************************************************** */ 30 | EOF 31 | } 32 | 33 | declare_accessor() { 34 | local type="$1" 35 | local name="$2" 36 | local tabs="" 37 | 38 | # Capitalize the first letter of the name 39 | local capitalized_name="$(echo $name | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')" 40 | 41 | for ((t = 0; t <= 12; t += 4)); do 42 | if (( ${#type} < 4 + $t )); then 43 | tabs+="\t" 44 | fi 45 | done 46 | 47 | echo " ${type}${tabs} get${capitalized_name}( void ) const;" 48 | echo " void set${capitalized_name}( const ${type} ${name} );" 49 | } 50 | 51 | implement_accessors() { 52 | local type="$1" 53 | local name="$2" 54 | local namespace="$3" 55 | 56 | # Capitalize the first letter of the name 57 | local capitalized_name="$(echo $name | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')" 58 | 59 | echo "$type $namespace::get${capitalized_name}( void ) const {" 60 | echo " return (this->_${name});" 61 | echo "}\n" 62 | echo "void $namespace::set${capitalized_name}( const $type $name ) {" 63 | echo " this->_${name} = ${name};" 64 | echo "}\n" 65 | } 66 | 67 | make_cpp() { 68 | local filename="${1}.cpp" 69 | 70 | put_header "$filename" 71 | cat <> "$filename" 72 | 73 | #include "${1}.hpp" 74 | 75 | #include 76 | 77 | EOF 78 | printf "${1}::${1}() " >> "$filename" 79 | 80 | if (( $# > 1 )); then 81 | printf ": " >> "$filename" 82 | for ((i = 2; i <= $#; i += 2)); do 83 | local upper_arg="$(echo "${@[i + 1]}" | sed 's/\([a-z]\)\([A-Z]\)/\1_\2/g; s/\([A-Z]\)\([A-Z][a-z]\)/\1_\2/g' | tr '[:lower:]' '[:upper:]')" 84 | 85 | printf "_${@[i + 1]}(DEFAULT_$upper_arg)" >> "$filename" 86 | if (( i < $# - 1 )); then 87 | printf "," >> "$filename" 88 | fi 89 | printf " " >> "$filename" 90 | done 91 | fi 92 | 93 | echo '{}' >> "$filename" 94 | 95 | if (( $# > 1 )); then 96 | printf "${1}::${1}(" >> "$filename" 97 | for ((i = 2; i <= $#; i += 2)); do 98 | printf " ${@[i]} ${@[i + 1]}" >> "$filename" 99 | if (( i < $# - 1 )); then 100 | printf "," >> "$filename" 101 | fi 102 | done 103 | printf " ) " >> "$filename" 104 | 105 | if (( $# > 1 )); then 106 | printf ": " >> "$filename" 107 | for ((i = 2; i <= $#; i += 2)); do 108 | printf "_${@[i + 1]}(${@[i + 1]})" >> "$filename" 109 | if (( i < $# - 1 )); then 110 | printf "," >> "$filename" 111 | fi 112 | printf " " >> "$filename" 113 | done 114 | fi 115 | echo '{}' >> "$filename" 116 | fi 117 | 118 | if (( $# > 1 )); then 119 | printf "${1}::${1}( const ${1} &other ) " >> "$filename" 120 | printf ": " >> "$filename" 121 | for ((i = 2; i <= $#; i += 2)); do 122 | printf "_${@[i + 1]}(other._${@[i + 1]})" >> "$filename" 123 | if (( i < $# - 1 )); then 124 | printf "," >> "$filename" 125 | fi 126 | printf " " >> "$filename" 127 | done 128 | else 129 | printf "${1}::${1}( const ${1} & ) " >> "$filename" 130 | fi 131 | 132 | echo '{}' >> "$filename" 133 | echo "${1}::~${1}() {}" >> "$filename" 134 | echo '' >> "$filename" 135 | 136 | # Generate getter and setter functions 137 | for ((i = 2; i <= $#; i += 2)); do 138 | implement_accessors "${@[i]}" "${@[i + 1]}" "${1}" >> "$filename" 139 | done 140 | 141 | if (( $# > 1 )); then 142 | echo "${1} &${1}::operator=( const ${1} &other ) {" >> "$filename" 143 | for ((i = 2; i <= $#; i += 2)); do 144 | echo " this->_${@[i + 1]} = other._${@[i + 1]};" >> "$filename" 145 | done 146 | else 147 | echo "${1} &${1}::operator=( const ${1} & ) {" >> "$filename" 148 | fi 149 | echo ' return (*this);' >> "$filename" 150 | echo "}" >> "$filename" 151 | echo '' >> "$filename" 152 | 153 | if (( $# > 1 )); then 154 | echo "std::ostream &operator<<( std::ostream &stream, const ${1} &instance ) {" >> "$filename" 155 | echo " stream << \"{${1}:\"" >> "$filename" 156 | for ((i = 2; i <= $#; i += 2)); do 157 | local capitalized_name="$(echo ${@[i + 1]} | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')" 158 | printf " << \"${@[i + 1]}=\" << instance.get${capitalized_name}()" >> "$filename" 159 | if (( i < $# - 1 )); then 160 | echo " << ','" >> "$filename" 161 | else 162 | echo " << '}';" >> "$filename" 163 | fi 164 | done 165 | else 166 | echo "std::ostream &operator<<( std::ostream &stream, const ${1} & ) {" >> "$filename" 167 | echo " stream << \"{${1}:{}}\";" >> "$filename" 168 | fi 169 | echo " return (stream);">> "$filename" 170 | echo "}" >> "$filename" 171 | } 172 | 173 | make_hpp() { 174 | local filename="${1}.hpp" 175 | local uppercase_param="$(echo "${1}" | sed 's/\([a-z]\)\([A-Z]\)/\1_\2/g; s/\([A-Z]\)\([A-Z][a-z]\)/\1_\2/g' | tr '[:lower:]' '[:upper:]')" 176 | 177 | # Create the .hpp file 178 | put_header "$filename" 179 | cat <> "$filename" 180 | 181 | #pragma once 182 | 183 | #ifndef ${uppercase_param}_HPP 184 | # define ${uppercase_param}_HPP 185 | 186 | 187 | # include 188 | 189 | EOF 190 | 191 | if ((2 <= $#)); then 192 | for ((i = 2; i <= $#; i += 2)); do 193 | local upper_arg="$(echo "${@[i + 1]}" | sed 's/\([a-z]\)\([A-Z]\)/\1_\2/g; s/\([A-Z]\)\([A-Z][a-z]\)/\1_\2/g' | tr '[:lower:]' '[:upper:]')" 194 | 195 | echo "# define DEFAULT_$upper_arg" >> "$filename" 196 | done 197 | echo '' >> "$filename" 198 | fi 199 | 200 | echo "class ${1} {" >> "$filename" 201 | 202 | if ((2 <= $#)); then 203 | echo 'protected:' >> "$filename" 204 | for ((i = 2; i <= $#; i += 2)); do 205 | local tabs="" 206 | for ((t = 0; t <= 12; t += 4)); do 207 | if (( ${#@[i]} < 4 + $t )); then 208 | tabs+="\t" 209 | fi 210 | done 211 | echo " ${@[i]}${tabs} _${@[i + 1]};" >> "$filename" 212 | done 213 | echo '' >> "$filename" 214 | fi 215 | 216 | echo "public:" >> "$filename" 217 | echo " ${1}();" >> "$filename" 218 | if ((2 <= $#)); then 219 | printf " ${1}(" >> "$filename" 220 | for ((i = 2; i <= $#; i += 2)); do 221 | printf " ${@[i]} ${@[i + 1]}" >> "$filename" 222 | if (( i < $# - 1 )); then 223 | printf "," >> "$filename" 224 | fi 225 | done 226 | echo " );" >> "$filename" 227 | fi 228 | echo " ${1}( const ${1} &other );" >> "$filename" 229 | echo " ~${1}();" >> "$filename" 230 | echo "" >> "$filename" 231 | 232 | if ((2 <= $#)); then 233 | for ((i = 2; i <= $#; i += 2)); do 234 | declare_accessor "${@[i]}" "${@[i + 1]}" >> "$filename" 235 | done 236 | echo '' >> "$filename" 237 | fi 238 | 239 | cat <> "$filename" 240 | ${1} &operator=( const ${1} &other ); 241 | }; 242 | 243 | std::ostream &operator<<( std::ostream &stream, const ${1} &instance ); 244 | 245 | 246 | #endif // ${uppercase_param}_HPP 247 | EOF 248 | } 249 | 250 | form() { 251 | if [ -z "$1" ]; then 252 | echo "Usage: form " 253 | return 1 254 | fi 255 | 256 | if (( $# % 2 == 0 )); then 257 | echo "Error: The number of arguments must be not even number" 258 | return 1 259 | fi 260 | 261 | if [ -f src/$1.cpp ] && ! [ -w src/$1.cpp ]; then 262 | echo "Error: File '$1.cpp' is not writable." 263 | else 264 | make_cpp "$@" 265 | echo "File '$1.cpp' successfully created." 266 | fi 267 | 268 | if [ -f src/$1.hpp ] && ! [ -w src/$1.hpp ]; then 269 | echo "Error: File '$1.hpp' is not writable." 270 | else 271 | make_hpp "$@" 272 | echo "File '$1.hpp' successfully created." 273 | fi 274 | } 275 | 276 | form "$@" 277 | -------------------------------------------------------------------------------- /installer.sh: -------------------------------------------------------------------------------- 1 | 2 | old_pwd=$PWD 3 | 4 | cd $HOME 5 | rm -rf cpp_class_creator 6 | 7 | mkdir cpp_class_creator_tmp 8 | cd cpp_class_creator_tmp 9 | 10 | git clone https://github.com/LuckyIntegral/Cpp-Class-Creator.git cpp_class_creator 11 | 12 | cp -r cpp_class_creator $HOME 13 | 14 | cd $HOME 15 | rm -rf cpp_class_creator_tmp 16 | 17 | cd $HOME/cpp_class_creator 18 | chmod +x $HOME/cpp_class_creator/form.sh 19 | chmod +x $HOME/cpp_class_creator/makefile.sh 20 | chmod +x $HOME/cpp_class_creator/installer.sh 21 | 22 | RC_FILE=$HOME/.zshrc 23 | if [[ "$SHELL" == *"bash"* ]]; then 24 | RC_FILE="$HOME/.bashrc" 25 | elif [[ "$SHELL" == *"zsh"* ]]; then 26 | RC_FILE="$HOME/.zshrc" 27 | fi 28 | 29 | if ! grep "form=" $RC_FILE &> /dev/null; then 30 | echo "Adding alias in file: $RC_FILE" 31 | echo -e "alias form=\"zsh $HOME/cpp_class_creator/form.sh\"" >> $RC_FILE 32 | fi 33 | 34 | if ! grep "makegen=" $RC_FILE &> /dev/null; then 35 | echo "Adding alias in file: $RC_FILE" 36 | echo -e "alias makegen=\"zsh $HOME/cpp_class_creator/makefile.sh\"" >> $RC_FILE 37 | fi 38 | 39 | if ! grep "ccc-update=" $RC_FILE &> /dev/null; then 40 | echo "Adding alias in file: $RC_FILE" 41 | echo -e "alias ccc-update=\"zsh $HOME/cpp_class_creator/installer.sh\"" >> $RC_FILE 42 | fi 43 | 44 | cd $old_pwd 45 | 46 | exec $SHELL 47 | 48 | echo "Installation complete" 49 | -------------------------------------------------------------------------------- /makefile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | make_makefile() { 4 | local filename="Makefile" 5 | local srcs=($(find . -type f -name "*.cpp" | awk '{print substr($0, 3)}')) 6 | 7 | if (( $# != 1 )); then 8 | echo "Usage: makegen " 9 | return 1 10 | fi 11 | 12 | # Create the .hpp file 13 | cat << EOF > "$filename" 14 | CXX = c++ 15 | NAME = ${1} 16 | RM = rm -rf 17 | 18 | OBJS_DIR = obj 19 | 20 | CXXFLAGS = -Wall -Wextra -Werror -MP -MD -std=c++98 -g 21 | MAKEFLAGS = -j\$(nproc) 22 | 23 | EOF 24 | echo 'SRCS = \' >> $filename 25 | 26 | for ((i = 1; i <= ${#srcs}; ++i)); do 27 | printf "\t\t${srcs[i]}" >> $filename 28 | if (( i != ${#srcs} )); then 29 | printf " \\" >> $filename 30 | fi 31 | printf "\\n" >> $filename 32 | done 33 | 34 | cat << EOF >> $filename 35 | 36 | OBJS = \$(SRCS:%.cpp=\${OBJS_DIR}/%.o) 37 | DEPS = \$(OBJS:%.o=%.d) 38 | 39 | all : \$(NAME) 40 | 41 | run : 42 | \$(RM) \$(OBJS_DIR) \$(NAME) 43 | @make --no-print-directory all 44 | @clear 45 | @./\${NAME}; 46 | @\$(RM) \$(OBJS_DIR) \$(NAME) 47 | 48 | test : 49 | \$(RM) \$(OBJS_DIR) \$(NAME) 50 | @make --no-print-directory all 51 | @clear 52 | @valgrind -s ./\${NAME}; 53 | @\$(RM) \$(OBJS_DIR) \$(NAME) 54 | 55 | \$(NAME) : \$(OBJS) 56 | \$(CXX) -o \$@ \$^ 57 | 58 | \${OBJS_DIR}/%.o: %.cpp 59 | @mkdir -p \$(dir \$@) 60 | \${CXX} \${CXXFLAGS} -c \$< -o \$@ 61 | 62 | clean : 63 | \$(RM) \$(OBJS_DIR) 64 | 65 | fclean : 66 | \$(RM) \$(OBJS_DIR) \$(NAME) 67 | 68 | re : 69 | \$(RM) \$(OBJS_DIR) \$(NAME) 70 | @make --no-print-directory all 71 | 72 | 73 | -include \$(DEPS) 74 | 75 | .PHONY: all clean fclean re run test 76 | EOF 77 | } 78 | 79 | make_makefile "$@" 80 | --------------------------------------------------------------------------------